Skip to main content
🤝

이 가이드는 인류와 AI가 함께 만드는 지식입니다.

이 콘텐츠는 Human + AI Partnership 철학 아래 모든 사람이 로봇·AI를 배울 수 있도록 무료로 제공됩니다. 당신의 질문과 기여가 다음 학생의 미래를 바꿉니다.

ROS 2 RViz Visualization & Advanced Plugins Guide 2026

Master RViz for 3D visualization of robot data. Build custom visualization plugins, create interactive dashboards, and publish visualization markers for real-time monitoring.

1. RViz Basics & Configuration

Launch and configure RViz:

# Launch RViz
rviz2

# Launch with config
rviz2 -d ~/my_robot.rviz

# Programmatic launch
ros2 launch my_robot_bringup rviz.launch.py

2. Publishing Visualization Markers

Send 3D visualization data to RViz:

#include <rclcpp/rclcpp.hpp>
#include <visualization_msgs/msg/marker.hpp>
#include <visualization_msgs/msg/marker_array.hpp>

class VisualizationPublisher : public rclcpp::Node {
 public:
  VisualizationPublisher() : Node("visualization_pub") {
    marker_pub_ = create_publisher<visualization_msgs::msg::Marker>(
      "visualization_marker", 10);

    marker_array_pub_ =
      create_publisher<visualization_msgs::msg::MarkerArray>(
        "visualization_marker_array", 10);

    timer_ = create_wall_timer(
      std::chrono::milliseconds(100),
      [this]() { publish_markers(); });
  }

 private:
  void publish_markers() {
    // Cube marker
    visualization_msgs::msg::Marker cube_marker;
    cube_marker.header.frame_id = "map";
    cube_marker.header.stamp = now();
    cube_marker.ns = "basic_shapes";
    cube_marker.id = 0;
    cube_marker.type = visualization_msgs::msg::Marker::CUBE;
    cube_marker.action = visualization_msgs::msg::Marker::ADD;
    cube_marker.pose.position.x = 1.0;
    cube_marker.pose.position.y = 0.0;
    cube_marker.pose.position.z = 0.5;
    cube_marker.pose.orientation.w = 1.0;
    cube_marker.scale.x = 1.0;
    cube_marker.scale.y = 1.0;
    cube_marker.scale.z = 1.0;
    cube_marker.color.r = 1.0;
    cube_marker.color.g = 0.0;
    cube_marker.color.b = 0.0;
    cube_marker.color.a = 1.0;

    marker_pub_->publish(cube_marker);

    // Sphere marker
    visualization_msgs::msg::Marker sphere_marker;
    sphere_marker.header.frame_id = "map";
    sphere_marker.header.stamp = now();
    sphere_marker.ns = "basic_shapes";
    sphere_marker.id = 1;
    sphere_marker.type = visualization_msgs::msg::Marker::SPHERE;
    sphere_marker.action = visualization_msgs::msg::Marker::ADD;
    sphere_marker.pose.position.x = 0.0;
    sphere_marker.pose.position.y = 1.0;
    sphere_marker.pose.position.z = 0.5;
    sphere_marker.pose.orientation.w = 1.0;
    sphere_marker.scale.x = 0.5;
    sphere_marker.scale.y = 0.5;
    sphere_marker.scale.z = 0.5;
    sphere_marker.color.r = 0.0;
    sphere_marker.color.g = 1.0;
    sphere_marker.color.b = 0.0;
    sphere_marker.color.a = 1.0;

    marker_pub_->publish(sphere_marker);
  }

  rclcpp::Publisher<visualization_msgs::msg::Marker>::SharedPtr
    marker_pub_;
  rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr
    marker_array_pub_;
  rclcpp::TimerBase::SharedPtr timer_;
};

3. Marker Types & Properties

Supported marker types in RViz:

// Marker types:
// ARROW = 0           (direction vector)
// CUBE = 1            (3D box)
// SPHERE = 2          (3D sphere)
// CYLINDER = 3        (cylinder)
// LINE_STRIP = 4      (connected line segments)
// LINE_LIST = 5       (unconnected line segments)
// CUBE_LIST = 6       (list of cubes)
// SPHERE_LIST = 7     (list of spheres)
// POINTS = 8          (point cloud)
// TEXT_VIEW_FACING = 9 (text label)
// MESH_RESOURCE = 10  (mesh from file)
// TRIANGLE_LIST = 11  (list of triangles)

// Example: Arrow marker
visualization_msgs::msg::Marker arrow;
arrow.type = visualization_msgs::msg::Marker::ARROW;
arrow.scale.x = 0.1;  // shaft diameter
arrow.scale.y = 0.2;  // head diameter
arrow.scale.z = 0.3;  // head length
arrow.pose.position.x = 1.0;
arrow.pose.position.y = 2.0;
arrow.pose.position.z = 0.5;
arrow.pose.orientation.w = 1.0;
arrow.color.r = 1.0;
arrow.color.a = 1.0;

4. Point Cloud Visualization

Display point clouds in RViz:

#include <sensor_msgs/msg/point_cloud2.hpp>
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>

class PointCloudVisualizer : public rclcpp::Node {
 public:
  PointCloudVisualizer() : Node("point_cloud_viz") {
    cloud_pub_ = create_publisher<sensor_msgs::msg::PointCloud2>(
      "point_cloud", 10);
  }

  void publish_point_cloud(
    const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud) {
    sensor_msgs::msg::PointCloud2 msg;
    pcl::toROSMsg(*cloud, msg);
    msg.header.frame_id = "map";
    msg.header.stamp = now();
    cloud_pub_->publish(msg);
  }

 private:
  rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr cloud_pub_;
};

5. Transform Visualization (TF)

Visualize robot transforms:

#include <tf2_ros/transform_broadcaster.h>

class TransformPublisher : public rclcpp::Node {
 public:
  TransformPublisher() : Node("transform_pub") {
    tf_broadcaster_ = std::make_unique<tf2_ros::TransformBroadcaster>(this);

    timer_ = create_wall_timer(
      std::chrono::milliseconds(100),
      [this]() { broadcast_transforms(); });
  }

 private:
  void broadcast_transforms() {
    geometry_msgs::msg::TransformStamped transform;
    transform.header.stamp = now();
    transform.header.frame_id = "base_link";
    transform.child_frame_id = "camera_link";
    transform.transform.translation.x = 0.1;
    transform.transform.translation.y = 0.0;
    transform.transform.translation.z = 0.5;
    transform.transform.rotation.w = 1.0;

    tf_broadcaster_->sendTransform(transform);
  }

  std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_;
  rclcpp::TimerBase::SharedPtr timer_;
};

6. Custom RViz Plugins

Develop custom visualization plugins:

// Custom panel plugin
#include <rviz_common/panel.hpp>

class MyCustomPanel : public rviz_common::Panel {
  Q_OBJECT
 public:
  MyCustomPanel(QWidget* parent = nullptr)
    : rviz_common::Panel(parent) {
    // Create UI elements
    layout_ = new QVBoxLayout();
    button_ = new QPushButton("Send Command");
    connect(button_, SIGNAL(clicked()), this, SLOT(on_button_clicked()));
    layout_->addWidget(button_);
    setLayout(layout_);
  }

  void onInitialize() override {
    // Initialize ROS 2 node
  }

 public Q_SLOTS:
  void on_button_clicked() {
    RCLCPP_INFO(rclcpp::get_logger("MyCustomPanel"),
                "Button clicked!");
  }

 private:
  QVBoxLayout* layout_;
  QPushButton* button_;
};

#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(MyCustomPanel, rviz_common::Panel)

7. Interactive Markers

Create interactive 3D objects:

#include <interactive_markers/interactive_marker_server.hpp>

class InteractiveMarkerServer {
 public:
  InteractiveMarkerServer(rclcpp::Node::SharedPtr node)
    : server_(node, "basic_controls", rclcpp::QoS(100)) {
    create_interactive_marker();
    server_.applyChanges();
  }

 private:
  void create_interactive_marker() {
    visualization_msgs::msg::InteractiveMarker int_marker;
    int_marker.header.frame_id = "map";
    int_marker.name = "my_marker";
    int_marker.scale = 1.0;

    visualization_msgs::msg::InteractiveMarkerControl control;
    control.orientation.w = 1.0;
    control.orientation.x = 1.0;
    control.interaction_mode =
      visualization_msgs::msg::InteractiveMarkerControl::MOVE_AXIS;

    int_marker.controls.push_back(control);
    server_.insert(int_marker);
  }

  std::shared_ptr<interactive_markers::InteractiveMarkerServer> server_;
};

8. 2D Navigation Overlays

Visualize navigation data:

# Display topics in RViz
# Map: /map (nav_msgs/OccupancyGrid)
# Global costmap: /global_costmap/costmap
# Local costmap: /local_costmap/costmap
# Path: /plan (nav_msgs/Path)
# Goal: /goal_pose (geometry_msgs/PoseStamped)
# Robot: /robot_pose (geometry_msgs/PoseStamped)

9. Performance Optimization for Visualization

Optimize RViz performance with large datasets:

// Decimate point clouds for visualization
#include <pcl/filters/voxel_grid.h>

pcl::PointCloud<pcl::PointXYZ>::Ptr decimate(
  const pcl::PointCloud<pcl::PointXYZ>::Ptr& input) {
  pcl::VoxelGrid<pcl::PointXYZ> sor;
  sor.setInputCloud(input);
  sor.setLeafSize(0.01f, 0.01f, 0.01f);

  pcl::PointCloud<pcl::PointXYZ>::Ptr output(
    new pcl::PointCloud<pcl::PointXYZ>);
  sor.filter(*output);
  return output;
}

// Reduce marker update frequency
// Only publish when data significantly changes
// Use marker deletion for old data

10. Best Practices

Key Takeaways

Use RViz for real-time visualization and debugging of robot systems. Publish markers for 3D data, visualize point clouds, and create interactive elements. Develop custom plugins for domain-specific visualization. Optimize for performance when handling large datasets.