Docs menu
Drive manually
Drive the car with the F710 gamepad or a Wiimote, and confirm the commands reach the motor and servo.
Manual driving is the first mode to run on a car and the quickest way to confirm the hardware works. It uses joy_teleop, which turns gamepad input into drive commands on /teleop.
Drive with the F710
Terminal 1 starts the hardware. The car does not move from this command alone.
ros2 launch f1tenth_stack bringup_launch.pyTerminal 2 starts manual control:
ros2 launch f1tenth_stack teleop_launch.pyHold LB, then push the left stick for speed and the right stick for steering. Releasing LB sends a zero command.
| Input | Command | Limit |
|---|---|---|
| Left stick, vertical (axis 1) | Speed | 5.0 m/s at full stick, forward and reverse |
| Right stick, horizontal (axis 3) | Steering | Car 1: 0.38 rad. Car 2: 0.436 rad. |
Each stick axis reads from −1 to 1. joy_teleop multiplies it by a scale and adds an offset, so the command is linear in the stick’s position:
with the full-stick steering, 0.38 rad on car 1 and 0.436 rad on car 2. Half stick forward asks for 2.5 m/s. The scale for steering is each car’s full-stick angle, measured by driving circles, and must fit inside the servo range; see Odometry calibration.
joy_teleop keeps publishing at 20 Hz while LB is released, with zeros. That is what makes LB a dead-man switch for manual driving, and also why teleop_launch.py must never run beside an autonomy node: its zeros win at the mux. See How the mux chooses.
The mapping is in joy_teleop.yamlGitHub. Upstream F1TENTH maps steering to axis 2, which is the left trigger on the F710 in XInput mode. The workspace corrects it to axis 3. Each car’s full-stick steering angle is in its profile’s calibration/joy_teleop.yaml, loaded on top of the shared file.
Check the commands
With the wheels off the ground, in a third terminal:
ros2 topic echo /joy --field buttons
ros2 topic echo /commands/servo/positionThe fifth value in buttons (index 4) reads 1 while LB is held. The servo position changes as the right stick moves and returns to the servo centre at rest: 0.366 on car 1, 0.5904 on car 2. If buttons never shows a 1 at index 4, the F710 is in DirectInput mode.
Drive with a Wiimote
A Wiimote, optionally in a Wii Wheel, is a second manual controller for demonstrations. It cannot enable autonomy: its driver publishes on /wiimote/joy, never on /joy, so no autonomy node sees its buttons. The package is src/racerbot_wiimote/GitHub.
Set up once
Install the Bluetooth and Wiimote libraries, then pair the Wiimote with its red SYNC button under the battery cover.
sudo apt install -y bluez xwiimote libxwiimote-dev pkg-config
ros2 run racerbot_wiimote_driver wiimote_connectwiimote_connect checks each layer (Bluetooth service, adapter, the hid-wiimote kernel driver, xwiimote, input group) and prints [ ok ] or [FAIL] with a fix for each. It is working when it prints Wiimote <address> connected. A Wiimote paired with SYNC reconnects when any of its buttons is pressed. A Wiimote paired with 1+2 forgets the car when it turns off.
If wiimote_connect reports the hid-wiimote kernel driver missing, the Jetson’s kernel was built without it. Building it is covered in docs/wiimote.mdGitHub.
Drive
Run the Wiimote’s control layer instead of teleop_launch.py, never beside it. Both publish on /teleop.
Terminal 1:
ros2 launch f1tenth_stack bringup_launch.pyTerminal 2:
ros2 launch racerbot_wiimote_driver wiimote_teleop_launch.pyTerminal 2 prints Wiimote connected and the Wiimote’s first LED goes solid.
| Wiimote, held sideways | Car |
|---|---|
| Hold 2 | Deadman. Every command is zero unless it is held. |
| 2 + A | Forward at 1.0 m/s |
| 2 + B | Reverse at 1.0 m/s |
| 2 + tilt | Steer, up to 0.34 rad at full tilt: less than the F710’s full stick on either car |
| Release 2 | Zero command |
If the Wiimote disconnects, goes out of range or sends nothing for 0.5 s, the driver reports no buttons held, so the command goes to zero. Check the steering direction with the wheels off the ground before the first drive. If tilting left turns the wheels right, set invert_accelerometer_y: true in wiimote_driver.yaml and restart terminal 2.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Nothing moves and ros2 topic echo /joy prints nothing |
No /joy: the F710 is in DirectInput mode, switched off, or the user is not in the input group. |
Run ros2 run racerbot_doctor doctor and follow its fix line. |
/joy changes but the wheels do not move |
The battery is off or flat, or the VESC is faulted. | Run the doctor with teleop running, holding LB. It traces the command to the motor. |
| Steering moves when the left trigger is pressed | The upstream axis mapping has come back into joy_teleop.yaml. |
Set steering to axis: 3. See docs/git-setup.mdGitHub before syncing f1tenth_system. |
| The car pulls to one side with the stick centred | The servo centre is off. | Run the odometry calibration wizard drive-straight step. |
Checked against
car 1 commit 881c409
and
car 2 commit 779c060, before the two workspaces merged.