Skip to main content

ROS 2 Isaac ROS Guide 2026

Isaac ROS is NVIDIA's collection of GPU-accelerated ROS 2 packages (called GEMs) that run on Jetson Orin and x86+CUDA machines. This guide covers cuVSLAM, Nvblox, AprilTag, and the NITROS zero-copy transport.

Isaac ROS GEMs Overview

GEMFunctionGPU speedup
isaac_ros_visual_slamcuVSLAM — stereo/mono visual odometry + loop closure5-10× vs CPU ORB-SLAM3
isaac_ros_nvblox3D occupancy & ESDF map from depth camera20× vs CPU Voxblox
isaac_ros_apriltagGPU AprilTag 3D pose detection4× vs apriltag_ros
isaac_ros_image_procGPU rectification, resize, crop, debayer3-5× vs image_proc
isaac_ros_stereo_image_procGPU disparity & point cloud from stereo pair8× vs stereo_image_proc
isaac_ros_depth_segmentationFreespace detection with FastDepth CNNReal-time on Nano
isaac_ros_dnn_inferenceTensorRT inference node (any ONNX model)Full TensorRT optimization

Setup — Docker-based (Recommended)

Isaac ROS requires a specific base container. NVIDIA provides pre-built containers for JetPack 6.x (Orin) and x86+CUDA 12.x.

# Pull the Isaac ROS base container (Jetson Orin / aarch64)
docker pull nvcr.io/nvidia/isaac/ros:aarch64-ros2_jazzy_2.1.0

# Or for x86 + CUDA
docker pull nvcr.io/nvidia/isaac/ros:x86_64-ros2_jazzy_2.1.0

# Run interactively with GPU and host network
docker run -it --rm \
  --runtime nvidia \
  --network host \
  --privileged \
  nvcr.io/nvidia/isaac/ros:aarch64-ros2_jazzy_2.1.0
# Inside container — install a GEM
apt-get update
apt-get install -y ros-jazzy-isaac-ros-visual-slam

# Source and verify
source /opt/ros/jazzy/setup.bash
ros2 pkg list | grep isaac_ros

cuVSLAM — GPU Visual SLAM

# Install
apt-get install -y ros-jazzy-isaac-ros-visual-slam

# Launch with RealSense D435i
ros2 launch isaac_ros_visual_slam isaac_ros_visual_slam_realsense.launch.py

Key Parameters

# In your launch file
visual_slam_node = ComposableNode(
    package="isaac_ros_visual_slam",
    plugin="nvidia::isaac_ros::visual_slam::VisualSlamNode",
    name="visual_slam_node",
    parameters=[{
        "enable_imu_fusion": True,     # IMU-aided VIO
        "gyro_noise_density": 0.000244,
        "accel_noise_density": 0.001862,
        "imu_frame": "imu_link",
        "enable_localization_n_mapping": True,  # full SLAM
        "enable_slam_visualization": True,
        "enable_landmarks_view": True,
        "path_max_size": 1024,
        "verbosity": 0,               # 0=quiet, 5=max debug
    }],
    remappings=[
        ("stereo_camera/left/image",  "/camera/infra1/image_rect_raw"),
        ("stereo_camera/left/camera_info",  "/camera/infra1/camera_info"),
        ("stereo_camera/right/image", "/camera/infra2/image_rect_raw"),
        ("stereo_camera/right/camera_info", "/camera/infra2/camera_info"),
        ("visual_slam/imu",           "/camera/imu"),
    ],
)

Output Topics

TopicTypeContent
/visual_slam/tracking/odometrynav_msgs/OdometryCamera pose estimate
/visual_slam/tracking/slam_pathnav_msgs/PathTrajectory history
/visual_slam/tracking/vo_pathnav_msgs/PathVisual odometry path
/visual_slam/map_pointssensor_msgs/PointCloud2SLAM map landmarks

Nvblox — GPU 3D Reconstruction

apt-get install -y ros-jazzy-nvblox

# Launch with RealSense D435
ros2 launch nvblox_ros nvblox_realsense.launch.py
# nvblox_ros node parameters
nvblox_node = ComposableNode(
    package="nvblox_ros",
    plugin="nvblox::NvbloxNode",
    parameters=[{
        "voxel_size": 0.05,            # meters — resolution
        "max_tsdf_update_hz": 10.0,
        "max_color_update_hz": 5.0,
        "max_mesh_update_hz": 5.0,
        "max_esdf_update_hz": 2.0,
        "esdf_2d": True,               # project to 2D for Nav2
        "esdf_slice_height": 0.3,
        "publish_esdf_distance_slice": True,
    }],
    remappings=[
        ("depth/image",        "/camera/depth/image_rect_raw"),
        ("depth/camera_info",  "/camera/depth/camera_info"),
        ("color/image",        "/camera/color/image_raw"),
        ("color/camera_info",  "/camera/color/camera_info"),
        ("pose",               "/visual_slam/tracking/odometry"),
    ],
)

Isaac ROS AprilTag

apt-get install -y ros-jazzy-isaac-ros-apriltag

# Quick launch
ros2 launch isaac_ros_apriltag isaac_ros_apriltag.launch.py \
  image_topic:=/camera/color/image_raw \
  camera_info_topic:=/camera/color/camera_info

# Output: /tag_detections (isaac_ros_apriltag_interfaces/AprilTagDetectionArray)
# Each detection has: id, family, pose (PoseWithCovarianceStamped), corners

# Supported families: 16h5, 25h9, 36h11, Circle21h7, Circle49h12, Custom48h12

NITROS — Zero-Copy GPU Transport

NITROS (NVIDIA Isaac Transport for ROS) eliminates CPU↔GPU memory copies between Isaac ROS nodes by keeping tensors on GPU memory and passing handles instead of serialized messages.

Standard ROS 2 vs NITROS

Camera → serialize → CPU pub → DDS → CPU sub → deserialize → GPU ← standard

Camera → GPU tensor → NITROS handle → GPU tensor → zero-copy ← NITROS

# NITROS is transparent — just use ComposableNodeContainer
# for nodes that support it (most Isaac ROS GEMs do)
container = ComposableNodeContainer(
    name="isaac_ros_container",
    namespace="",
    package="rclcpp_components",
    executable="component_container_mt",
    composable_node_descriptions=[
        # NITROS kicks in automatically for GPU-capable nodes
        image_proc_node,
        visual_slam_node,
        nvblox_node,
    ],
    output="screen",
)

# Verify NITROS is active
ros2 topic echo /nitros_bridge/statistics

Common Issues

cuVSLAM: tracking lost immediately

Verify stereo calibration. Infra1/infra2 images must be time-synchronized. Enable AE lock on RealSense: rs-enumerate-devices -e.

Nvblox: 'CUDA out of memory' on Jetson Nano

Nano has only 4GB unified memory. Increase voxel_size to 0.1 or disable color updates (max_color_update_hz: 0).

NITROS: 'No NITROS type registered'

Both publisher and subscriber nodes must be in the same ComposableNodeContainer. NITROS doesn't cross process boundaries.

AprilTag detections flicker

Tag must be in 36h11 family by default. Check image_rect (undistorted) is used, not raw. Ensure tag size_m matches physical tag.

Container not found in NGC

NGC requires login: docker login nvcr.io -u \$oauthtoken -p <API_KEY>. Get API key from ngc.nvidia.com.

Next Steps