이 가이드는 인류와 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.py2. 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 data10. Best Practices
- Namespacing: Use unique namespaces for markers to avoid conflicts
- Performance: Decimate large point clouds, reduce marker count
- Color: Use consistent color schemes for different data types
- Transparency: Use alpha channel to layer overlapping visualizations
- Update Rate: Balance visualization frequency with performance
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.