RViz2 Workflow Guide — JetRacer Autonomous Stack¶
Overview¶
RViz2 is never started on the Jetson Nano by default.
The Jetson Nano has limited RAM (~4 GB shared) and GPU memory; running RViz2
locally during autonomous driving would compete with YOLO inference and lane
detection for GPU/CPU resources.
The recommended workflow is:
Quick Start¶
On the Jetson Nano¶
# 1. Source workspace
source /opt/ros/foxy/setup.bash
source ~/ros2_ws/install/setup.bash
# 2. Run the health check
bash src/jetracer_bringup/scripts/health_check.sh
# 3. Launch the stack (headless, no RViz)
ros2 launch jetracer_bringup jetracer.launch.py use_rviz:=false
# 4. In a second terminal: start autonomy
ros2 launch jetracer_bringup autonomy.launch.py
On the Laptop (remote RViz2)¶
# 1. Source ROS 2 (same distro as Jetson)
source /opt/ros/foxy/setup.bash
# 2. Set ROS_DOMAIN_ID to match the Jetson
export ROS_DOMAIN_ID=0 # must match value on Jetson
# 3. Verify the Jetson is reachable
ros2 node list # should show /jetracer_hardware, /lane_following, etc.
ros2 topic list # should show /cmd_vel, /scan, /odom, /lane_following/*
# 4. Launch RViz2 with the autonomy profile
rviz2 -d $(ros2 pkg prefix jetracer_description)/share/jetracer_description/rviz/autonomy.rviz
# OR via launch file:
ros2 launch jetracer_description rviz.launch.py use_rviz:=true rviz_profile:=autonomy
ROS 2 Network Setup¶
Requirements¶
| Setting | Value |
|---|---|
| ROS 2 distro | Same on Jetson and laptop (e.g. foxy) |
ROS_DOMAIN_ID |
Same integer on both machines (default: 0) |
| Network | Same LAN subnet, or direct Ethernet link |
| Multicast | Enabled on the network switch (most home routers: yes) |
| Firewall | UDP ports unrestricted between the two hosts |
Verify DDS Discovery¶
# On laptop — should list Jetson nodes within 2–3 seconds:
ros2 node list
# If empty, try forcing the Jetson IP:
export ROS_DISCOVERY_SERVER=192.168.1.XXX:11811 # only if using Connext
# OR for CycloneDDS, add a cyclone_dds.xml with peer IP
CycloneDDS Unicast (when multicast fails)¶
If your switch blocks multicast (common on managed switches), force unicast:
<!-- ~/cyclone_dds.xml on BOTH machines -->
<CycloneDDS>
<Domain>
<Discovery>
<Peers>
<Peer address="192.168.1.XXX"/> <!-- Jetson IP -->
<Peer address="192.168.1.YYY"/> <!-- Laptop IP -->
</Peers>
</Discovery>
</Domain>
</CycloneDDS>
Available RViz2 Profiles¶
| Profile | Config File | Best For |
|---|---|---|
autonomy |
autonomy.rviz |
Lane following debug (default) |
lane_following |
autonomy.rviz |
Alias for autonomy |
description |
jetracer.rviz |
Robot model + TF only |
navigation |
navigation.rviz |
Nav2 + SLAM map |
slam |
slam.rviz |
SLAM building |
# Switch profiles:
ros2 launch jetracer_description rviz.launch.py use_rviz:=true rviz_profile:=navigation
Topics Visible in autonomy.rviz¶
| Display | Topic | Type | Default |
|---|---|---|---|
| RobotModel | /robot_description |
std_msgs/String |
✅ On |
| TF | — | TF2 tree | ✅ On |
| LiDAR Scan | /scan |
sensor_msgs/LaserScan |
✅ On |
| Odometry | /odom |
nav_msgs/Odometry |
✅ On |
| Lane Centerline | /lane_following/path |
nav_msgs/Path |
✅ On |
| Waypoints | /lane_following/path_viz |
geometry_msgs/PoseArray |
✅ On |
| Lane Markers | /lane_following/markers |
visualization_msgs/MarkerArray |
✅ On |
| Lane Debug Image | /lane_following/debug_image/compressed |
sensor_msgs/CompressedImage |
❌ Off |
| YOLO Image | /perception/yolo_debug/compressed |
sensor_msgs/CompressedImage |
❌ Off |
Image displays are disabled by default — enabling them adds ~2–8 Mbps of network traffic per topic. Enable only on a wired or fast Wi-Fi connection.
TF Frame Tree¶
odom ─────────────────────────────────── (EKF → published by ekf_filter_node)
└─ base_footprint
└─ base_link
├─ camera_link x=0.115m forward, z=0.045m
│ └─ camera_link_optical (rotated −π/2 around Z, −π/2 around X)
├─ imu_link z=0.020m
├─ laser_link z=0.100m, yaw=π (upside-down RPLidar)
├─ front_left_steering_link
├─ front_right_steering_link
└─ jetson_link
Verify TF Tree¶
# Quick check:
ros2 run tf2_tools view_frames
# Generates /tmp/frames.pdf showing the complete tree
# Check specific transform:
ros2 run tf2_ros tf2_echo base_link camera_link
ros2 run tf2_ros tf2_echo odom base_footprint
ros2 run tf2_ros tf2_echo base_link laser_link
Lane Following Markers (lane_following/markers)¶
Three markers are published per control cycle when enable_markers: true:
| ID | Type | Meaning |
|---|---|---|
| 0 | SPHERE (gold) |
Lookahead / target waypoint |
| 1 | ARROW (blue) |
Steering command direction (scaled by speed) |
| 2 | CUBE (color) |
Tracking state: 🟢 GOOD / 🟡 WEAK / 🔴 LOST |
Markers have lifetime.sec = 1 — they disappear automatically if the node stops.
Disable Markers on Jetson (save CPU)¶
Or set in main_config.yaml:
Viewing Image Topics Remotely¶
Image topics are compressed (sensor_msgs/CompressedImage) and already bandwidth-optimised. To view them without RViz2:
# rqt_image_view (lightweight):
ros2 run rqt_image_view rqt_image_view /lane_following/debug_image/compressed
# Raw stats:
ros2 topic hz /lane_following/debug_image/compressed # should be ≤5 Hz
ros2 topic hz /csi_cam_0/image_raw/compressed # should be ~20 Hz
Validation Commands¶
# List all topics
ros2 topic list
# Check lane following topics
ros2 topic info /lane_following/path
ros2 topic info /lane_following/markers
ros2 topic echo /lane_following/status --once
ros2 topic hz /lane_following/control_fps
# Check sensor topics
ros2 topic hz /scan
ros2 topic hz /odom
ros2 topic hz /csi_cam_0/image_raw/compressed
# TF checks
ros2 run tf2_tools view_frames
ros2 run tf2_ros tf2_echo base_link camera_link
ros2 run tf2_ros tf2_echo odom base_footprint
# Launch RViz2 manually
rviz2 -d $(ros2 pkg prefix jetracer_description)/share/jetracer_description/rviz/autonomy.rviz
Remaining Limitations¶
| Limitation | Reason | Workaround |
|---|---|---|
| RViz2 cannot run on Jetson Nano during autonomous driving | RAM/GPU budget | Use remote laptop workflow |
camera_info topic uses camera_link frame (not optical) |
gscam publishes with frame_id from launch arg |
Set frame_id: camera_link — already done |
lane_following/debug_image/compressed is 320×240 |
Processed in 320×240 space | Acceptable; upscale in rqt_image_view if needed |
| No 3D lane boundary visualization | Lane detector works in 2D BEV | nav_msgs/Path + MarkerArray approximate this |
| Steering joint state not animated in robot model | No joint_state_publisher running (correct for HW) | Accept static model — avoids zero-flooding /joint_states |