INSTALL THE ROS 2 DRIVER.
The NeoRacer ships with the Jetson, ROS 2 Humble, and the sensors wired, but not the driver that ties them together. This is the one-time setup that clones the driver into a workspace, builds it with , and gets the sensors and motors live behind a single teleop command.
THE SYSTEM SPECS.
Every NeoRacer follows the same naming so scripts and instructions line up. Car ID is the number on your unit, so Car 1 is at 192.168.1.101 on the neoracer-1 network.
SYSTEM DEPENDENCIES.
On the car, install the system packages the driver and its tooling need (ROS 2 joystick stack, rqt, build tools, the Jetson kernel headers for the joystick driver), then the Python libraries.
bashsudo apt update && sudo apt upgrade -y sudo apt install ros-humble-rqt-common-plugins -y sudo apt install ros-humble-joy ros-humble-joy-linux ros-humble-teleop-twist-joy -y sudo apt install vim tmux screen terminator -y sudo apt install ufw -y sudo apt install joystick -y sudo apt install dkms git build-essential nvidia-l4t-kernel-headers -y sudo apt install python3-pip -y
bashpip3 install opencv-python==4.8.1.78 pip3 install numpy==1.26.2 pip3 install nptyping==1.4.4 pip3 install jupyterlab
ALIASES AND DIRECTORIES.
Add these to ~/.bashrc so the workspace is sourced in every shell and teleop launches the whole stack. Then make the two working directories the tooling expects.
bash# in ~/.bashrc source ~/osracer_ws/install/setup.bash # or ros2_ws, depending on your stack alias teleop="ros2 launch neoracer_ros2_driver teleop.launch.py" alias rqt_image_view="ros2 run rqt_image_view rqt_image_view" alias rqt_runtime_monitor="ros2 run rqt_runtime_monitor rqt_runtime_monitor"
bashmkdir ~/data mkdir ~/jupyter_ws
THE JUPYTERLAB SERVICE.
JupyterLab is the one thing that does auto-start, so you can reach the car from a browser with no SSH. Open the firewall port, then create the service.
bashsudo ufw allow 8888 export PATH="$HOME/.local/bin:$PATH" sudo vim /etc/systemd/system/jupyterlab.service
bash[Unit] Description=Jupyter Lab After=network.target [Service] Environment=PATH=/home/nvidia/.local/bin:/usr/local/bin:/user/bin:/bin Type=simple User=nvidia ExecStart=/bin/bash -c "source /home/nvidia/osracer_ws/install/setup.bash && source /opt/ros/humble/setup.bash && /home/nvidia/.local/bin/jupyter lab --no-browser --ip=0.0.0.0 --port=8888 --NotebookApp.token=''" WorkingDirectory=/home/nvidia/jupyter_ws Restart=always [Install] WantedBy=multi-user.target
bashsudo loginctl enable-linger $USER sudo systemctl daemon-reload sudo systemctl enable jupyterlab.service sudo systemctl start jupyterlab.service sudo journalctl -u jupyterlab.service -f # to debug
THE JOYSTICK DRIVER.
The controller uses the xpad kernel module, built against your kernel with DKMS so it survives kernel updates. This is why the kernel headers went in back in step 02.
bashsudo git clone https://github.com/paroj/xpad.git /usr/src/xpad-0.4 sudo dkms install -m xpad -v 0.4
THE COLCON BUILD.
Clone the driver and the Richbeam LakiBeam LiDAR driver into your workspace's src, then build the whole stack with colcon. The --symlink-install flag lets you edit Python files without rebuilding every time.
bashcd ~/osracer_ws/src # or ~/ros2_ws, depending on your stack git clone https://github.com/Neobotics-Foundation-Inc/neoracer_ros2_driver.git git clone https://github.com/RichbeamTechnology/Lakibeam_ROS2_Driver.git cd .. colcon build --symlink-install source install/setup.bash source ~/.bashrc # should see no errors now
RUN THE STACK.
The driver is not auto-started, you bring it up when you want it, in any terminal:
bashracecar teleop # wraps: ros2 launch neoracer_ros2_driver teleop.launch.py
That single launch starts the whole stack:
- controller: the ESP32 bridge. Owns the serial link to the OSCORE board, reads the and wheel , forwards the Flysky RC, and turns
/motorcommands into motor and servo motion. Publishes/imu,/odom, and/joy. - gamepad_node, mux_node, throttle_node: the drive pipeline. Take
/drive(autonomy) or/gamepad_drive(manual), arbitrate, scale to speed caps, send through to/motor. - camera: the USB webcam, MJPG frames out as JPEG-in-Image on
/camera. - led_matrix: the 8x8 dot-matrix display on the back of the car, takes text on
/led_matrix/command. - lakibeam1: the Lakibeam scanner over UDP, publishes
/scan.
For headless work, JupyterLab is already serving at http://192.168.1.[100 + Car ID]:8888 over the car's Wi-Fi, so a browser on the car's network reaches it with no SSH.
The driver publishes the topics; the racecar-neo-library (the rc.* Python API you write programs against) wraps them. Install it with the racecar-neo-installer, then your code talks to the same /drive, /scan, and /camera that teleop spawns.
