Close

Locomotion with a PS4 controller

A project log for Upkie wheeled biped robot

A homemade wheeled biped that can balance, crouch or turn around. It proudly stands on broomsticks and 3D printed parts.

tasts-robotsTast's Robots 11/13/2022 at 16:560 Comments

Upkie communicates with a regular PS4 controller. While this is not a key robotic feature, it is both cool (especially with kids 😃) and convenient to control the robot via Bluetooth. Before trying it out I was concerned about potential lags, or the Raspberry Pi loosing its connection to the controller, but the field summary after using it for months is: it just works.

Here are my configuration-troubleshooting notes, turned project log 😉

Pairing the PS4 controller to the Raspberry Pi

The setup instructions are not specific to Upkie: we can connect a PS4 controller to any Raspberry Pi. Start with the Bluetooh command line:

sudo bluetoothctl

Enable the agent with the following four instructions:

agent on
discoverable on
pairable on
default-agent

Then start scanning for devices. The terminal should start listing scan results with all the Bluetooth devices around you:

scan on

While the command tool is scanning, press and hold both the Share and PS buttons on your controller to switch it to pairing mode. Keep holding the buttons at the same time until it starts flashing white light. When it does, check the terminal output for a new line like this one:

[NEW] Device AC:FD:93:14:25:D3 Wireless Controller

Note down the controller MAC address (here AC:FD:93:14:25:D3). Check that the controller is still flashing and do:

connect CONTROLLER_MAC_ADDRESS

That should be it! If everything went well, you should see a "successful connection" message appear in the terminal, like so:

[bluetooth]# connect AC:FD:93:FD:68:0F
Attempting to connect to AC:FD:93:FD:68:0F
[CHG] Device AC:FD:93:FD:68:0F Connected: yes
[CHG] Device AC:FD:93:FD:68:0F UUIDs: 00001124-0000-1000-8000-00805f9b34fb
[CHG] Device AC:FD:93:FD:68:0F UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device AC:FD:93:FD:68:0F ServicesResolved: yes
[CHG] Device AC:FD:93:FD:68:0F Paired: yes
Connection successful

Finally, trust the controller so that it can connect after a reboot:

[bluetooth]# trust AC:FD:93:FD:68:0F

That's it! The controller should now appear as a regular Linux joystick device in /dev/input/js*. That's where the Joystick source in Vulp (Upkie's motion control software) will look for it.

Troubleshooting a reconnection issue

Sometimes, for instance if you pair the PS4 controller to another device (say, a PS4...), the connection may fail with an error like this:

[bluetooth]# connect AC:FD:93:FD:68:0F
Attempting to connect to AC:FD:93:FD:68:0F
[CHG] Device AC:FD:93:FD:68:0F Connected: yes
Failed to connect: org.bluez.Error.Failed
[CHG] Device AC:FD:93:FD:68:0F Connected: no

Watch out for errors in /var/log/syslog by running the following command while connecting:

tail -f /var/log/syslog

The error I faced was the following one:

Apr 12 23:33:25 raspi bluetoothd[471]: Can't get HIDP connection info
Apr 12 23:33:26 raspi bluetoothd[471]: connect error: Invalid exchange (52)

A workaround for this is to unpair:

[bluetooth]# paired-devices
Device AC:FD:93:FD:68:0F Wireless Controller
[bluetooth]# remove AC:FD:93:FD:68:0F
[DEL] Device AC:FD:93:FD:68:0F Wireless Controller

Then connect again:

[bluetooth]# scan on
Discovery started
[CHG] Controller DC:A6:32:D6:AA:D7 Discovering: yes
...
[NEW] Device AC:FD:93:FD:68:0F Wireless Controller
[bluetooth]# connect AC:FD:93:FD:68:0F
Attempting to connect to AC:FD:93:FD:68:0F
[CHG] Device AC:FD:93:FD:68:0F Connected: yes
[CHG] Device AC:FD:93:FD:68:0F UUIDs: 00001124-0000-1000-8000-00805f9b34fb
[CHG] Device AC:FD:93:FD:68:0F UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device AC:FD:93:FD:68:0F ServicesResolved: yes
[CHG] Device 76:63:59:CE:8E:69 RSSI: -90
[CHG] Device AC:FD:93:FD:68:0F Paired: yes
[CHG] Device FA:0D:AC:BF:8E:C9 RSSI: -97
Connection successful

Hoping this helps. Happy roaming!

Discussions