Skip to content

Sport Client (Joystick) — C++ Example ​

Source: rbq_sdk/cpp/example/src/rbq_sport_client_joy.cpp

Drives the robot using a gamepad / joystick via the SportClient API.
Analog sticks stream continuous Move velocity commands; buttons trigger discrete actions (Damp, StandUp/Down, gait switches, acrobatics).

How it works ​

Two concurrent parts run together:

PartRateWhat it does
Main thread (joystick)~100 HzReads joystick events, pushes discrete SportCmd entries onto a queue, updates atomic velocity setpoints
Control loop thread10 HzDrains the command queue first; if empty, calls sport.Move(vx, vy, vyaw)

The control loop calls sport.SetNoReply(true) — commands are sent fire-and-forget without waiting for an RPC acknowledgement.

Prerequisites ​

  • RBQ SDK built and installed — see C++ SDK Overview.
  • A Linux joystick device (e.g. Logitech F710) available at /dev/input/js*.
  • Robot stack running and reachable on the network interface you pass as argv[1].

Build ​

From rbq_sdk/cpp/example/:

bash
bash scripts/setup.bash
bash scripts/build.bash

Binary: bin/rbq_sport_client_joy

Run ​

bash
./bin/rbq_sport_client_joy [networkInterface] [joystickPath]

# Simulator / on-robot stack — interface defaults to lo
./bin/rbq_sport_client_joy

# Real robot — pass the interface that reaches it
# auto-detect joystick:
./bin/rbq_sport_client_joy eth0
# explicit joystick device:
./bin/rbq_sport_client_joy eth0 /dev/input/js1

If no joystick path is given, the binary auto-detects js* devices: it prefers a device whose name contains "Logitech", "gamepad", "Xbox", or "wireless", then falls back to the first available node, then /dev/input/js0.
The JOY environment variable can also override the path.

Gamepad bindings ​

The mapping follows the Logitech F710 / Xbox layout recognized by the Linux joystick driver.

Button chords (checked first) ​

Buttons pressedRobot action
L2 + BDamp — high-damping emergency stop
L2 + A (1st press)StandUp — lock joints in standing position
L2 + A (2nd press)StandDown — go prone
STARTDefaultMode — unlock / default gait
L2 + STARTRunningMode — high-speed gait
L2 + XRecoveryStand — stand up from fall
R1 + XClimb — stair-climb gait
BACKStopMove — stop in place

Double-click bindings ​

A second press within 400 ms of the first triggers the action.

ButtonAction
Double XLeftSideGait
Double YRightSideGait

Analog stick velocity (continuous) ​

AxisMaps toMax value
Left stick Y (push forward)vel_x (forward)±0.55 m/s
Left stick X (push left)vel_y (lateral)±0.35 m/s
Right stick Xvyaw (yaw rate)±1.0 rad/s

A deadzone of 0.12 is applied to all axes before scaling.

Key implementation notes ​

  • lock_toggle_to_prone: L2+A alternates between StandUp and StandDown on successive presses via a boolean toggle — matching the behavior of the A2 robot's built-in controller.
  • Double-click detection: A consume_double() lambda tracks the last edge timestamp. If a second edge arrives within kDoubleClickWindow (400 ms), the action fires and the counter resets.
  • R2 as virtual button: The RT trigger (AXIS_RT) is treated as a button by comparing the axis value against 0 — idle is −1, full press is +1.
  • Error streak logging: Consecutive errors are counted; a message is printed every 50 failures to avoid log spam.

See also ​

This user manual is intended for RBQ users.