Docs menu
Set up the workspace
Clone the car workspace onto a Jetson, install its dependencies, build it, and confirm the car and its hardware are found.
Both cars already have a built workspace at ~/racerbot-ws, cloned from the one workspace repository both cars share. Follow this page to set up a new Jetson, to rebuild after a fresh clone, or to understand what the existing install contains. Run every command on the Jetson.
Requirements
- A Jetson Orin Nano Super with JetPack 7.2 and Ubuntu 24.04.
- ROS 2 Jazzy installed natively, with
rosdepinitialized. - CUDA at
/usr/local/cuda, which JetPack installs. Onlyrange_libcneeds it. - Network access to GitHub.
1. Clone with submodules
Both cars clone the same repository, Racerbot-Car-Workspace. Several packages are Git submodules: particle_filter, range_libc, transport_drivers, the team repositories racerbot_a and racerbot_b, web_dashboards, and realsense-ros. realsense-ros is car 2’s camera driver and needs Intel’s librealsense to build, so car 1 leaves it uninitialized. An empty src/realsense-ros folder is skipped by the build.
Car 2, or any computer with librealsense installed:
git clone --recurse-submodules https://github.com/sfu-racerbot/Racerbot-Car-Workspace.git ~/racerbot-wsCar 1:
git clone https://github.com/sfu-racerbot/Racerbot-Car-Workspace.git ~/racerbot-ws
cd ~/racerbot-ws
git submodule update --init --recursive src/particle_filter src/range_libc src/transport_drivers src/racerbot_a src/racerbot_b src/web_dashboardsIf the submodule folders exist but are empty, the submodules were never initialized. Run the git submodule update line above on car 1, or this on car 2:
cd ~/racerbot-ws
git submodule update --init --recursiveThen run the set-up script once in the new clone:
cd ~/racerbot-ws
tools/dev/setup_clone.shIt installs the workspace’s pre-commit hook, which refuses a commit that adds a file over 95 MiB, and prints the car this machine is: rb1 on car 1, rb2 on car 2, or dev box: set RACERBOT_CAR for the simulator on a computer that is not a registered car. A Jetson that prints an unknown serial error is not in machines.yamlGitHub yet; add its serial there before driving it, as docs/car-profiles.mdGitHub describes. On a development computer, choose the car in every terminal instead:
export RACERBOT_CAR=rb1f1tenth_system is a copy of the upstream repository with local fixes committed on top, vendored rather than a submodule, so it arrives with a normal clone. Read docs/git-setup.mdGitHub before pulling upstream changes into it.
2. Install dependencies
rosdep reads every package’s package.xml and installs the system packages they declare, including slam_toolbox from apt.
source /opt/ros/jazzy/setup.bash
cd ~/racerbot-ws
rosdep install --from-paths src --ignore-src -r -y3. Build
source /opt/ros/jazzy/setup.bash
cd ~/racerbot-ws
colcon build --symlink-install --parallel-workers 1The build is working when it ends with Summary: N packages finished and no failed count. Warnings are normal. A full build takes several minutes. --parallel-workers 1 builds one package at a time, because a parallel build can run out of the Jetson’s 8 GB of memory.
--symlink-install links the Python, launch and YAML files into install/ instead of copying them, so edits to those files take effect at the next launch without a rebuild. A workspace built without it holds copies, and an edit to a YAML in src/ changes nothing until the package is rebuilt. A rebuild is still needed after changing package.xml, setup.py or C++ code, or after adding or removing files. While working on one package, build only that package:
colcon build --symlink-install --packages-select gap_followIf the build state becomes confusing, delete the generated folders and rebuild. build/, install/ and log/ contain only build output.
rm -rf build install log && colcon build --symlink-install --parallel-workers 14. Build the GPU ray caster
particle_filter localizes the car by asking range_libc what the LiDAR would see from each candidate pose. colcon does not build range_libc’s Python module, and particle_filter’s configuration requires the CUDA version. Build it once by hand. It installs into the user’s Python packages and survives later workspace rebuilds.
source /opt/ros/jazzy/setup.bash
export PATH=/usr/local/cuda/bin:$PATH
cd ~/racerbot-ws/src/range_libc/pywrapper
rm -rf build RangeLibc.cpp
WITH_CUDA=ON python3 setup.py install --userThe build is working when the output contains Compiling with CUDA support and lines ending in for 'sm_87', the Orin’s GPU architecture. It takes about two minutes. Then confirm the GPU version is the one Python loads:
cd ~/racerbot-ws
python3 -c "import range_libc; print(range_libc.SHOULD_USE_CUDA)"It prints True when the build used CUDA. False means the build fell back to the CPU version, and particle_filter fails on its first scan. The full measurements are in docs/gpu-acceleration.mdGitHub.
5. Install the MPC solver (optional)
The MPC steering law needs the osqp solver. The other three steering laws do not.
pip install --user --break-system-packages osqp==1.1.3
python3 -c "import osqp; print(osqp.__version__)"The second command prints 1.1.3. --break-system-packages is needed because Ubuntu 24.04 protects the system Python, and --user keeps the package in the home folder.
6. Check the IMU calibration
imu_bridge reads each IMU’s mount rotation and calibration from the car’s profile, cars/rb1/imu/Car 1 or cars/rb2/imu/Car 2, and the BNO085 bridge and calibration tools from tools/imu_calibration/GitHub. Both arrive with the clone, so no separate repository is needed. Car 2’s mount yaw and BNO085 position are not measured yet; see IMU fusion before turning on any feature that uses the IMU’s forward axis.
7. Set up device access
The VESC, the car 1 LiDAR, the gamepad, car 1’s webcam and each car’s BNO085 need a fixed device name or a group membership. The udev rules live in /etc/udev/rules.d/, outside the repository; copies of car 1’s are in tools/udev/GitHub.
| Car 1 | Car 2 | |
|---|---|---|
| VESC | 99-vesc.rules: /dev/sensors/vesc for USB ID 0483:5740 | 99-vesc.rules: /dev/sensors/vesc for USB ID 0483:5740 |
| LiDAR | 99-hokuyo.rules: /dev/sensors/hokuyo for USB ID 15d1:0000 | NetworkManager profile hokuyo: static 192.168.0.15/24 on enP8p1s0 |
| Groups | input (gamepad), video (webcam), i2c (BNO085), dialout | input (gamepad), i2c (BNO085), dialout |
After adding or editing a udev rule, apply it without rebooting:
sudo udevadm control --reload-rules && sudo udevadm triggerAdd a user to a group, then log out and back in. Group membership only applies to sessions started afterwards.
sudo usermod -aG input,video,i2c,dialout $USER8. Check the result
Source both setup files, start bringup, and run the doctor in a second terminal.
Terminal 1:
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 doctorThe setup is complete when the doctor’s first line names this car (Car rb1 or Car rb2) and its last line reads 0 FAIL. See the pre-run checklist for what each check means.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Package 'gap_follow' not found |
The terminal has not sourced install/setup.bash, or the build failed. |
Source both setup files in that terminal. Check the build summary for failed. |
| A build dies with no useful error, or the Jetson freezes | The build ran out of memory. | Rebuild with --parallel-workers 1. |
ModuleNotFoundError: No module named 'range_libc' |
Step 4 was skipped, or ~/.local was cleaned. |
Run step 4. |
importlib.metadata.PackageNotFoundError when a node starts |
A partial or mixed install for that package. | rm -rf build/<pkg> install/<pkg>, then rebuild it. |
Permission denied on /dev/sensors/vesc or /dev/input/js0 |
The user is missing a group, or the session predates the group change. | Step 7, then log out and back in. |
A launch stops with CarMismatchError |
RACERBOT_CAR names the other car on a registered Jetson. |
unset RACERBOT_CAR in that terminal, then relaunch. |
A launch stops with UnknownCarError |
The Jetson’s serial is not in machines.yaml, or RACERBOT_CAR is unset on a development computer. |
Register the serial, or set RACERBOT_CAR=rb1 or rb2 on a development computer. |
The build fails in realsense2_camera on car 1 |
src/realsense-ros was initialized, and librealsense is not installed. |
git submodule deinit -f src/realsense-ros, then rebuild. |
Checked against workspace commit 556284c.