Docs menu
Pre-run checklist
The physical checks and the racerbot_doctor self-check to run before the car moves, and how to read the doctor's report.
Run this checklist at the start of every session and after any change to code or configuration. It takes about two minutes. It supplements the club’s vehicle testing procedure (SOP-TECH-02), which governs every run on hardware.
Before power
- The battery is charged, undamaged, and handled as set out in SOP-TECH-01.
- The car is on a stand with its wheels off the ground for the first run of new or changed code.
- The F710’s switch is set to X (XInput) and the gamepad is switched on.
- Everyone present knows where the battery switch is, and one person can reach it.
- For an autonomy run, one person stands at the battery switch for the whole run.
Run the doctor
racerbot_doctor checks every device layer by layer: USB, kernel driver, device file and permissions, ROS driver process, message rate, message content. It stops at the first broken layer of each device and prints a fix for it. It only reads: it never publishes on a topic and never opens the VESC’s or LiDAR’s serial port, the camera or the gamepad, so it is safe to run at any time.
Terminal 1, the hardware drivers:
source /opt/ros/jazzy/setup.bash
source ~/racerbot-ws/install/setup.bash
ros2 launch f1tenth_stack bringup_launch.pyTerminal 2:
source /opt/ros/jazzy/setup.bash
source ~/racerbot-ws/install/setup.bash
ros2 run racerbot_doctor doctorWhy layer by layer. A device works only if every layer under it works: a ROS driver cannot publish from a device file that does not exist, and the file does not exist without the kernel driver. Checking from the bottom up, and stopping at the first failure, names the cause rather than its symptoms. An unplugged VESC fails at USB, and the doctor skips the device file, the driver process and the message rate above it, instead of reporting four failures that all mean “unplugged”.
The car is ready when the last line reads 0 FAIL. A WARN does not stop a run, but read it. Without bringup running, the doctor checks only the hardware layers and reports the ROS layers as INFO, not as failures.
The source is src/racerbot_doctor/GitHub. Every threshold is in racerbot_doctor/car.py, next to a note saying where it comes from.
Read the report
| Status | Meaning |
|---|---|
PASS |
This layer works. |
FAIL |
This layer is broken. The layers above it are skipped, and a fix: line follows. |
WARN |
Works, but not as it should, for example a low battery or no webcam. |
INFO |
Nothing wrong. Usually that bringup is not running, so the doctor stopped there. |
SKIP |
Not checked, and the line says why. |
The exit code is 0 when nothing failed, 1 when something failed, and 2 when the doctor itself crashed, so scripts can use it.
What each section checks
| Section | Layers, bottom to top |
|---|---|
| VESC | USB 0483:5740 → /dev/ttyACM* → /dev/sensors/vesc readable and writable → port not held by another program → vesc_driver_node running → /sensors/core at 25 Hz or more → fault_code 0 → battery |
| LiDAR | Car 1: USB 15d1:0000 → /dev/sensors/hokuyo → urg_node_driver running → /scan at 30 Hz or more → beams with returns. Car 2: Ethernet link, address, ping and TCP port, then the same ROS layers. |
| Gamepad | F710 receiver in XInput mode → /dev/input/js* → both js* and event* readable (input group) → joy_node running → /joy at 5 Hz or more |
| Camera | Car 1: a UVC webcam at /dev/video0, readable (video group). Car 2: the RealSense. Camera problems are always WARN, because the car drives without it. |
| Bringup | ackermann_mux, ackermann_to_vesc_node and vesc_to_odom_node running → /odom at 25 Hz or more → the base_link to laser transform is 0.26 0 0.11 |
| Environment | ROS_DISTRO is jazzy, the workspace is sourced, ROS_DOMAIN_ID is not the test domain 79, and the simulator is not running beside the real drivers |
Battery
The doctor reads the pack voltage that the VESC measures, published as voltage_input on /sensors/core. The cars use 3S LiPo packs.
| Reading | Verdict |
|---|---|
| Under 5.0 V | FAIL: no battery, the VESC is running on USB power only |
| Under 10.2 V (3.4 V per cell) | FAIL: critically low |
| Under 10.8 V (3.6 V per cell) | WARN: low |
| Over 12.75 V (4.25 V per cell) | WARN: higher than a full 3S pack |
The VESC sees only the total voltage, so one weak cell can hide behind a healthy total. Check cells with a balance checker before charging.
When LB does nothing
Start teleop_launch.py as well, then run the doctor while holding LB and pushing the left stick. A Drive path section follows the command hop by hop, /joy → /teleop → /ackermann_cmd → /commands/motor/speed, and names the first hop that goes quiet. If it ends with PASS motor command, ROS is working and the fault is below it: the battery switch, the ESC power or the motor wiring.
Limitations
- The doctor cannot tell whether the F710 gamepad itself is switched on, because the USB receiver looks the same either way. Press a button while
ros2 topic echo /joyruns if in doubt. - Without root it cannot see another user’s process holding the VESC’s serial port.
- The battery reading has not been checked against a multimeter.
Checked against
car 1 commit 0265263
and
car 2 commit b81b291, before the two workspaces merged.