Skip to content

RViz2 Visualization — Robot Visualization in ROS 2

RViz2 (Robot Visualizer) is the primary 3D visualization tool for ROS 2. This tutorial covers RViz2 setup, key displays for each robot type, and advanced visualization techniques for debugging and demos.

Learning Objectives

  • Understand RViz2 panel architecture and displays
  • Configure RViz2 for mobile robot, manipulator, and aerial drone
  • Use the pre-built .rviz configuration for this course
  • Add custom displays: TF tree, sensors, camera images, navigation overlays
  • Interpret robot state visually for debugging

1. RViz2 Architecture

RViz2 is a ROS 2 node that subscribes to topics and renders them in 3D. It does not run physics or simulation — it only visualizes data.

┌──────────────────────────────────────────┐
│           RViz2 Main Window              │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │                                    │  │
│  │        3D Viewport                 │  │
│  │   (Robot, sensors, paths)          │  │
│  │                                    │  │
│  └────────────────────────────────────┘  │
│                                          │
│  ┌─────────┐ ┌────────────┐ ┌────────┐  │
│  │ Displays│ │ Toolbars    │ │ Views  │  │
│  └─────────┘ └────────────┘ └────────┘  │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │      Properties Panel               │  │
│  │  (Topic, color, style, size)        │  │
│  └────────────────────────────────────┘  │
└──────────────────────────────────────────┘

Key Displays by Category

Category Display Topic Purpose
Robot RobotModel /robot_description 3D mesh from URDF
Robot TF /tf Coordinate frames
Sensors LaserScan /scan 2D lidar points
Sensors PointCloud2 /depth/points 3D point cloud
Sensors Image /camera/color/image_raw Camera feed
Sensors Camera /camera/color/camera_info Camera overlay
Sensors IMU /imu/data Orientation arrows
Navigation Map /map Occupancy grid
Navigation Path /plan Planned trajectory
Navigation Pose /goal_pose Target pose
Navigation Trajectory /smoothed_plan Smoothed path
Control Marker /visualization_marker Debug markers

2. Launching RViz2

From Docker Container

# Method 1: Launch with pre-configured file (recommended)
rviz2 -d $(find robot_description)/config/robot.rviz

# Method 2: Blank RViz (configure manually)
rviz2

# Method 3: With specific config
rviz2 -d /path/to/config.rviz

Launch Arguments

rviz2 [OPTIONS]
  -d <file>    Load display config from file
  -f <frame>   Set fixed frame
  -s           Use zero_INITIAL pose (no camera animation)
  -h           Show help

3. Essential Displays Configuration

3.1 RobotModel Display

Shows the robot from URDF in the 3D viewport.

Display Name:    RobotModel
Topic:           /robot_description (Parameter)
Alpha:           1.0 (opaque)
Description Source: Parameter
TF Prefix:       (leave empty)

Alpha < 1 is useful when you want to see sensors through the robot body.

3.2 TF Display

Shows the coordinate frame tree. Essential for understanding the robot's frame hierarchy and detecting frame mismatches.

Display Name:    TF
Enabled:         true
Marker Scale:    0.3 m (axis length)
Show Axes:       true
Show Names:      true
Update Interval: 0 (as fast as possible)

Debug tip

If TF tree is broken (missing frames), check: 1. ros2 node list — is robot_state_publisher running? 2. ros2 topic list | grep tf — are TF messages arriving? 3. ros2 run rqt_tf_tree rqt_tf_tree — visual frame tree

3.3 LaserScan Display

2D lidar data shown as points in the horizontal plane.

Display Name:    LaserScan
Topic:           /scan
Color Transformer: Intensity  (color by reflectance)
Queue Size:      10
Style:           Points  (or Flat Squares)
Size (m):        0.05   (visual size, not physical resolution)
Position Transformer: XYZ

Color modes: - Flat Color: single color for all points - Intensity: gray value based on return intensity (reflectance) - AxisColor: color by distance from sensor

3.4 Image Display

RGB or depth camera feed. Overlaid on a plane in 3D space OR as a floating panel.

Display Name:    Image
Topic:           /depth_camera/color/image_raw
Transport Hint:  raw  (or compressed, theora)

# For depth image:
Topic:           /depth_camera/depth/image_raw

Image vs Camera display

Use Image for a floating 2D panel. Use Camera display for a 3D overlay on a plane (requires CameraInfo).


4. Visualization by Robot Type

4.1 Mobile Robot — SLAM & Navigation

The mobile robot uses laser scan + odometry + IMU. Configure RViz for map building:

1. RobotModel → /robot_description
2. TF → all frames visible
3. LaserScan → /scan (red points, size 0.05m)
4. Map → /map (show occupancy grid, alpha 0.7)
5. Path → /plan (nav2 planned path, blue)
6. Pose → /goal_pose (nav2 target, green arrow)
7. Odometry → /diff_drive/odometry (arrow marker)

Key RViz interactions: - 2D Pose Estimate tool: click on map to set initial robot pose (for AMCL) - 2D Nav Goal tool: click on map to set navigation target - Scroll wheel: zoom - Middle click + drag: pan - Right click + drag: rotate view

4.2 Manipulator Arm — MoveIt2

The arm uses joint state + TF for FK/IK visualization:

1. RobotModel → /robot_description
2. TF → joint frames visible
3. MotionPlanning (plugin) → InteractiveMarkers for arm control
4. JointStates → /joint_states (trajectory playback)
5. Trajectory → /display_planned_path (planned arm motion)
6. Path → /execute_trajectory (executed path, different color)

Key interactions: - In MotionPlanning plugin: drag end-effector to set target pose - Green arm = planned path, Orange arm = executed path - Trajectory animation speed adjustable in properties

4.3 Aerial Drone — Gazebo + Camera

Drone needs altitude awareness and camera feed:

1. RobotModel → /robot_description
2. TF → base_link with IMU orientation visible
3. Image → /depth_camera/color/image_raw
4. Image → /depth_camera/depth/image_raw (pseudo-color)
5. Pose → /drone/pose (mavros or ground truth)
6. Path → /trajectory (planned flight path)

4.4 Visual Navigation — VSLAM

Visual SLAM keyframe + map + trajectory:

1. RobotModel → /robot_description
2. PointCloud2 → /vslam/map_points (SLAM 3D map)
3. PoseArray → /vslam/keyframes (camera poses)
4. Path → /vslam/trajectory (estimated path)
5. Image → /depth_camera/color/image_raw
6. Marker → /vslam/debug_markers (feature points)

5. Pre-built Configuration

The course provides a pre-configured RViz file at:

$(find robot_description)/config/robot.rviz

This includes: - Grid (XY plane, 10m × 10m) - RobotModel with alpha=0.5 - TF tree (axes + frame names) - LaserScan (red, 0.05m points) - Camera image panel

To use:

rviz2 -d $(find robot_description)/config/robot.rviz

To save changes:

File → Save Config As → ~/ros2_ws/src/robot_description/robot_description/config/robot.rviz


6. Advanced: Programmatic Display Control

You can control RViz displays programmatically using rviz_visual_tools:

#!/usr/bin/env python3
"""Add custom markers and trajectories to RViz programmatically."""
import rclpy
from rclpy.node import Node
from visualization_msgs.msg import Marker, MarkerArray
from geometry_msgs.msg import PoseStamped

class RvizVisualizer(Node):
    def __init__(self):
        super().__init__('rviz_visualizer')
        # Marker publisher
        self.marker_pub = self.create_publisher(Marker, '/visualization_marker', 10)
        # Path publisher
        self.path_pub = self.create_publisher(PoseStamped, '/debug_path', 10)

    def add_sphere_marker(self, position, rgba=(1, 0, 0, 1), ns="debug"):
        """Add a sphere marker at position."""
        marker = Marker()
        marker.header.frame_id = "base_link"
        marker.type = Marker.SPHERE
        marker.action = Marker.ADD
        marker.pose.position.x = position[0]
        marker.pose.position.y = position[1]
        marker.pose.position.z = position[2]
        marker.scale.x = marker.scale.y = marker.scale.z = 0.05
        marker.color.r, marker.color.g, marker.color.b, marker.color.a = rgba
        marker.ns = ns
        self.marker_pub.publish(marker)

7. Common Debugging Patterns

Pattern: Robot model not loading

1. Check /robot_description topic exists:
   ros2 topic list | grep robot_description

2. Verify URDF is valid:
   ros2 run robot_state_publisher robot_state_publisher

3. Check xacro can generate URDF:
   xacro $(find robot_description)/urdf/mobile_robot.urdf.xacro

Pattern: LaserScan not showing

1. Verify scan topic exists:
   ros2 topic list | grep scan

2. Check message rate:
   ros2 topic hz /scan

3. Check fixed frame in RViz:
   Fixed Frame must be "world" or "odom" (not "base_link")

Pattern: Map not appearing in Navigation

1. SLAM Toolbox must be running (not just Nav2)
2. Fixed frame in RViz must be "map"
3. Check map topic:
   ros2 topic type /map
   # should be nav_msgs/OccupancyGrid

8. Keyboard Shortcuts

Key Action
f Focus on robot (center view on selected frame)
s Toggle side panel
t Toggle tool properties
n Toggle all panels
q Quit
r Reset view
Space Reset all views
w Show/hide grid

References