Sunday, November 5, 2017

Simulating Fetch Robotics Freight with Steam Controller Teleop

Hunter College owns Freight and Fetch robots.  I was asked to help figure out how to reduce the speed of the joystick teleop input for the Freight robot.  The catch is, I don't have physical access to either the robot or the joystick it ships with.  Instead, I had to simulate the robot and attempt to control it using the only joystick I have on hand: a Steam controller.

Having never dealt with ROS or robots in general, this was the start of a journey. The documentation for fetch_teleop is pretty non-existent, so this article documents what I did and will hopefully serve as a reference for someone else who wants to do something similar.  

Installing ROS

I used a Macbook Pro on OS X El Capitan.  ROS doesn't officially support OS X, though there are guides for compiling ROS for OS X.  That process seems pretty hairy, so I decided instead to use an Ubuntu VM on VirtualBox.

The Fetch manual is a great resource and I followed the tutorial on Gazebo simulation.  It calls for an older version of ROS, ROS Indigo running on Ubuntu 14.04.  

Follow this guide to install ROS indigo.

Install Gazebo and Fetch Robotics simulation

Install gazebo (per guide):
curl -ssL | sh
Then, install the fetch gazebo simulation:
sudo apt-get update
sudo apt-get install ros-indigo-fetch-gazebo-demo

Install Steam Controller drivers for Ubuntu

SC Controller is a great project which provides a driver for and allows you to use your Steam Controller outside of Steam.  To install:

wget -nv -O Release.key sudo apt-key add - < Release.key 
sh -c "echo 'deb /' > /etc/apt/sources.list.d/sc-controller.list"
sudo apt-get update 
sudo apt-get install sc-controller

After installing, restart your VM.  Your Steam controller should show up as jsX, where X is the index number of the joystick under /dev/input.  That means /dev/input/js0 if you have no existing joysticks, and js2 for me since I have virtualbox guest additions as /dev/input/js0 and /dev/input/js1.  You can test that the joystick is working using joytest:

sudo jstest /dev/input/jsX

Install Joy and fetch_teleop

Next, we need to install the joy and fetch_teleop packages.  fetch_teleop maps joystick input to control signals for the robot.  fetch_teleop subscribes to the /joy topic, which is published by joy.  joy publishes the state of a Linux joystick.

sudo apt-get install ros-indigo-joy ros-indigo-fetch-teleop

Run Simulation

Now we're ready to start the simulation!

Launch the master node and playground:

roslaunch fetch_gazebo playground.launch robot:=freight

If you'd like, to play around, you can use your keyboard to control the robot.  In a new terminal, run:

rosrun teleop_twist_keyboard

Next, we need to start the Joy node and tell it which controller to use.  Remember jsX from earlier.   In a new terminal:

rosparam set joy_node/dev "/dev/input/js2"
rosrun joy joy_node

To test that joy is publishing messages, we can echo the /joy topic in a new terminal:

rostopic echo joy

You should see output like this when you move the joystick:

  seq: 9847
    secs: 312
    nsecs: 756000000
  frame_id: ''
axes: [-0.0, -0.0, 1.0, -0.0, -0.0, 1.0, -0.0, -0.0]
buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Configure and launch fetch_teleop

The Fetch & Freight manual doesn't mention how to configure the speed/acceleration when using Fetch Robotics' bundled joystick. This is mostly what I discovered from reading the source of fetch_teleop.

fetch_teleop gets parameters from the parameter server under the following namespace:


There are 5 components, each of which have their own params:


Since I'm simulating the Freight robot, which doesn't have an arm, head, or torso, we only care about moving the base.  For my Steam Controller I had to remap the inputs for deadman from the default of button 3 to button 0 (the A button) and axes from w=3 and x=0 to w=1 and x=0 (the left joystick) like so:

rosparam set teleop/base/button_deadman 0
rosparam set teleop/base/axis_x 0
rosparam set teleop/base/axis_w 1

Then, we can change the maximum velocity and acceleration along the w and x axes:

rosparam set teleop/base/max_windup_time 0.25
rosparam set teleop/base/max_acc_x 0.5
rosparam set teleop/base/max_acc_w 1.5
rosparam set teleop/base/max_vel_x 1.0
rosparam set teleop/base/max_vel_w 1.5

And finally, run fetch_teleop in a new terminal:

rosrun fetch_teleop joystick_teleop

You should now be able to steer the robot.  Be sure to hold down the deadman, or else your input will be ignored!