Files
ros-raspbot-v2/teleop/README.md
T

4.5 KiB

Teleop

Container for manually driving the robot via keyboard or joystick. Both modes publish TwistStamped on /cmd_vel as required by the mecanum drive controller.

The container is not started by the default docker compose up — it must be launched explicitly with docker compose run.

Prerequisites

Build the image once before first use:

docker compose build teleop

Keyboard

docker compose run --rm teleop teleop-keyboard

Use the standard teleop_twist_keyboard bindings (i, ,, j, l, etc.) to drive. Press k to stop.

Joystick

docker compose run --rm teleop teleop-joystick

The script starts joy_node and teleop_twist_joy_node together; both are stopped when you press Ctrl+C.

The controller layout defaults to ps5. Override JOY_CONFIG with any config name from the teleop_twist_joy package (e.g. ps4, xbox, atk3):

JOY_CONFIG=xbox docker compose run --rm teleop teleop-joystick

To list all available configs:

docker compose run --rm teleop bash -c \
  "ls \$(ros2 pkg prefix teleop_twist_joy)/share/teleop_twist_joy/config/"

The container expects the joystick at /dev/input/js0. If your device is at a different path, set JOYSTICK_DEV before running:

JOYSTICK_DEV=/dev/input/js1 docker compose run --rm teleop teleop-joystick

Running from a remote machine

The container includes a FastDDS profile that restricts DDS discovery and traffic to a single network interface, preventing traffic leaking onto unintended interfaces (e.g. a wired link alongside the robot's Wi-Fi).

The interface defaults to wlan0. Override it with the FASTDDS_INTERFACE variable:

FASTDDS_INTERFACE=wlan1 docker compose run --rm teleop teleop-keyboard

Or set it permanently in your .env file:

FASTDDS_INTERFACE=wlan0

The robot containers do not currently apply this FastDDS profile, so both ends must be reachable on the configured interface for DDS discovery to succeed. Ensure the ROS_DOMAIN_ID matches on all machines.

Useful commands

Working out the network interface to bind to

TODO: show how to find the correct network interface to bind FastDDS to... TODO: Create a script to do this?

Look at the output of ip addr, and see which interface is on the sane network as the robot.

For example, this output

___snip___
3: wlp195s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 84:9e:56:9c:a1:b5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.207/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp195s0
       valid_lft 79183sec preferred_lft 79183sec
    inet6 fe80::32f4:b953:b7ca:e415/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
___snip___

shows that interface wlp195s0 is on the same network as my robot at ip address 192.168.1.166/24.

You should therefore set FASTDDS_INTERFACE=wlp195s0.

Working out the correct devices to pass through

I am assuming you have a PS DualSense controller, because this is what I used to test.

cat /proc/bus/input/devices | grep -A 8 "DualSense"
N: Name="Sony Interactive Entertainment DualSense Wireless Controller"
P: Phys=
S: Sysfs=/devices/pci0000:00/0000:00:08.3/0000:c7:00.0/usb3/3-1/3-1:1.3/0003:054C:0CE6.0001/input/input3
U: Uniq=a0:ab:51:b5:7e:fb
H: Handlers=event3 js0
B: PROP=0
B: EV=20000b
B: KEY=7fdb000000000000 0 0 0 0
B: ABS=3003f
--
N: Name="Sony Interactive Entertainment DualSense Wireless Controller Motion Sensors"
P: Phys=
S: Sysfs=/devices/pci0000:00/0000:00:08.3/0000:c7:00.0/usb3/3-1/3-1:1.3/0003:054C:0CE6.0001/input/input5
U: Uniq=a0:ab:51:b5:7e:fb
H: Handlers=event5 js1
B: PROP=40
B: EV=19
B: ABS=3f
B: MSC=20
--
N: Name="Sony Interactive Entertainment DualSense Wireless Controller Touchpad"
P: Phys=
S: Sysfs=/devices/pci0000:00/0000:00:08.3/0000:c7:00.0/usb3/3-1/3-1:1.3/0003:054C:0CE6.0001/input/input6
U: Uniq=a0:ab:51:b5:7e:fb
H: Handlers=mouse0 event6
B: PROP=5
B: EV=b
B: KEY=2420 10000 0 0 0 0
B: ABS=260800000000003

This shows me that the primary control input is on js0 and event3. So I would need to launch the container like this:

# Note that /dev/input/js0 is already mapped by default
JOYSTICK_EVENT_DEV=/dev/input/event3 docker compose run --rm teleop teleop-joystick

Test the joystick is bound in the container

Install the jstest package

# In the container
apt update
apt-get install joystick
# Inside the container, the joystick is always mapped to js0
jstest /dev/input/js0