PS2 Controller for ROS2 projects

I love open source stuff and re-purposing existing technologies to new interfaces. I have seen PS2 controllers used in robotics projects before and it just makes a lot of sense. I just never knew how it worked. Now that I do I wanted to make something that would reduce the friction for others hoping to do the same integration.

I actually thought I wrote a whole post about how I hooked up a Playstation2 controller to an Arduino and some radio modules for controlling robotics projects - but I guess I imagined it. I wrote a protocol that made it possible to use the same 'controller' (transmitter) for several projects including a track-drive robot and a mini 3D-printed robotic arm. Actually wiring up the hardware side of the project was easy and there are some very reliable libraries available since people have been doing this for over a decade.

Now that I'm ROS-curious I realized that I should adapt this same idea but make it easier to interface with a (networked) ROS project. Having one controller for all your robots reduces clutter and makes you look like a bad ass Wizard of Oz.

I always wanted a Power Glove but I'll settle for a universal PS2 controller

Project Goals:

  • Make something simple and useful
  • Use widely available, cheap and reliable components
    • PS2 controller
    • ESP8266-like wifi-enabled microcontroller ( I used a ESP8266-12F "Wemos D1 Mini" )
  • Share it - Github
  • Don't reinvent anything / KISS
    • ROS conventions / things to use:
      • the /joy message type - the standard for depicting joystick positions and button presses
      • rosbridge_server - to recieve /joy topic messages, a simple launchfile-defined node

To be clear this is not revolutionary at all. I'm duct-taping together several useful things that already work well.

Output / Finished Product :

A PS2 controller connected to a microcontroller that connects to wifi and ultimately to the websocket server provided by rosbridge_server. All the code and accompanying documentation (diagrams) hosted in github. It would be nice if it didn't look janky, but that's asking a lot.

I'm trying to get into the habit of starting with a drawing.

This makes it clearer that most of the work will go into the code on the microcontroller side to make it compatible with rosbridge_websocket.

Development

I used Postman to test the assumption that I can just send these JSON messages in rosbridge_protocol myself:

First connect to :9090 and then send JSON according to rosbridge protocol

However, this is already making two assumptions about the ROS project, really dictating two dependencies. First, you have to have rosbridge_websocket ( part of rosbridge_server ) running in the ROS project and second, the project has subscribe to /joy topic messages.

Wiring

Your wiring will depend on your hardware, but here is how it mapped out for me

PS2 Controller Wire ESP8266 Pin GPIO Number
VCC 3.3V -
GND GND -
Brown (D1 / DATA) D6 GPIO12
Orange (D0 / CMD) D7 GPIO13
Yellow (CS / ATT/Attention) D3 GPIO0
Blue (CLK/Clock) D5 GPIO14
Green & Gray Not Connected -

Configure the wire variables to GPIO pins

#define PS2_DAT 12 //  D6  
#define PS2_CMD 13 // D7  
#define PS2_SEL 0 //  D3  this is CS  
#define PS2_CLK 14 // D5

On the ESP8266 side it just connects to the rosbridge_websocket server, the starts reading the transmitter inputs with PS2X and blasting them out as JSON messages at a blistering speed.

cellophane = removable heatshrink

Demo Project

I decided to build an example implementation that can also be used for testing. It uses a ros:jazzy -based Docker image with only the minimum required dependencies and a simple ROS node that subscribes and logs messages on the /joy topic. I'm pretty pleased with how simple it is to setup.

One speedbump here was that without any subscribers to /joy, the rosbridge_websocket node was rejecting the JSON messages from the transmitter - it had nothing to do with them. For the time being I have the transmitter 'advertising' the /joy topic when it starts up, letting rosbrige_websocket know that there will be interest and that it should be processed.

With a simple docker compose up a ROS launchfile brings up the rosbridge_websocket server and starts a node subscribed to /joy . I hope that it can help others get projects bootstrapped and show how bridging can be an alternative to trying to implement ROS all the way down to the microcontroller level where it may not be necessary.

GitHub - anthonyrobertson/ros_ps2_tx
Contribute to anthonyrobertson/ros_ps2_tx development by creating an account on GitHub.

Room for Improvement

This feels like a 'minimum viable' stopping point, but there are a lot of things that could be improved.

  • Namespacing / transmitter ID - in case there are multiple ROS namespaces on the network, or even more than one remote for the same ROS project
  • Setup WifiManager or something like it to make the wifi configuration easier
  • Make a landing page for the transmitter - allows getting info, maybe even changing configs
  • Better documentation in the README especially regarding the wiring and configuring of the script before flashing