Skip to content

PS4 Controller Setup

A PS4 Joystick is used for car control and teleoperation. Most of the fleet's controllers are AceGamer clones that identify themselves as Sony DualShock 4s, and some cars have a genuine Sony one. This guide describes how to set up the controller to work with the car.

Everything here runs on the car itself (over SSH or on its touchscreen), not inside a container.

Install the driver

This only needs to be done once per car. The setup script does it.

JetPack's kernel leaves out Linux's PlayStation controller driver. Without it, the controllers get the wrong button mapping, report no battery level, and the clones won't pair over Bluetooth at all. roboracer_ws builds the driver from source and keeps it installed across reboots and kernel updates:

~/roboracer_ws/scripts/install_ds4_driver.sh

Pair a controller

This only needs to be done once per car and controller combination.

  1. Plug the controller into the car with a USB cable. The driver runs a handshake the clones need before they will pair over Bluetooth. A genuine Sony controller doesn't need it, so you can skip this step for one. Note the controller's address, which appears in this folder name:
    ls /sys/class/power_supply/        # ps-controller-battery-<MAC>
    
  2. Unplug the cable. Start bluetoothctl and turn scanning on:
    bluetoothctl
    
    [bluetooth]# scan on
    
  3. Hold the Share and PS buttons for about 5 seconds, until the light bar flashes in quick double blinks. Within a few seconds a line with the controller's address appears:
    [NEW] Device <MAC> Wireless Controller
    
  4. Pair, trust and connect it while it's still flashing, then leave bluetoothctl:

    [bluetooth]# pair <MAC>
    [bluetooth]# trust <MAC>
    [bluetooth]# connect <MAC>
    [bluetooth]# scan off
    [bluetooth]# quit
    
    After the first couple of characters of an address, Tab fills in the rest. pair ends with Pairing successful and connect with Connection successful, and the light bar stops flashing. Keep the scan on until then: pair can only find a controller the scan has just seen.

    bluetoothctl also prints a line like Controller CC:47:40:.... That's the car's own Bluetooth, not the game controller, so don't pair with that address. Lines about other devices nearby, such as phones and badges, are normal.

From then on, the PS button alone reconnects the controller. It shows up as /dev/input/js* whether it's connected by Bluetooth or by cable.

Pairing from the touchscreen instead of steps 2 to 4

After step 1 and holding Share and PS until the light bar flashes, you can also pair from the car's Bluetooth settings. Plug a keyboard into the car, press the Windows key, and search for "Bluetooth".

Look for the controller in the list of available devices:

Bluetooth Settings Disconnected Joystick

Select the Wireless Controller and click pair:

Bluetooth Settings Connected Joystick

Things that are easy to get wrong:

  • PS alone never starts pairing. On a controller that hasn't been paired, it blinks for a few seconds while it looks for a known car, then turns off. That's normal and says nothing about the battery. Pairing needs Share + PS held for about 5 seconds.
  • The USB step is required for the clones, and does nothing on a car without the driver.
  • Battery level, with the controller connected either way: cat /sys/class/power_supply/ps-controller-battery-*/capacity
  • To list, unpair or reset controllers later: ~/roboracer_ws/scripts/bluetooth_controller_manager.sh

Driving with the controller

The controller drives the car whenever the teleop or navigation plan is running, for example airfield project up teleop (see Intro to Car Hardware). The joystick and the VESC driver each run in their own pane.

Control What it does
Hold L1 Drive with the controller. Let go and the car stops.
Left stick, left/right Steering
Right stick, up/down Speed
L2 pressed all the way, while holding L1 Turbo: a higher top speed
Hold R1 Let the autonomy stack drive. Let go and the car stops.
Press R2 Let the autonomy stack drive without holding a button. Any other button or stick stops the car.
D-pad left/right Trim the steering center, saved to the car's car.lua
D-pad up/down Trim the speed offset, saved to the car's car.lua

Stick layout

joystick_mode in ~/roboracer_ws/packages/ut_automata/config/joystick.lua picks which sticks steer and drive:

  • "both" (default): left stick left/right steers, right stick up/down drives.
  • "left": the left stick does both.
  • "right": the right stick does both.
joystick_mode = "left";  -- or "right" or "both"

Troubleshooting

The wrong device is used as the joystick

The car's touchscreen can also appear as /dev/input/js0. If the joystick pane reads the wrong device, change joystick_port="/dev/input/js0" to joystick_port="/dev/input/js1" in joystick.lua.

The controller isn't found when the plan starts

Turn the controller on before you launch the plan. The joystick pane looks for it at startup.