Skip to content

RViz Marker 发送基本形状

目标: 展示如何使用 visualization_msgs/msg/Marker 消息向 RViz 发送基本形状。

教程级别: 中级

预计耗时: 15 分钟

注意:本教程假设你已经熟悉编写 ROS 2 C++ 节点并使用 colcon 构建包。

与 RViz 的许多其他显示类型不同,Marker 显示不需要 RViz 提前了解数据的含义——你的节点直接通过 visualization_msgs/msg/Marker 消息发送基本几何对象,RViz 会把它们渲染为箭头、方块、球体、圆柱体等 marker。

本教程展示如何发送四种基本形状:立方体、球体、圆柱体和箭头。我们将编写一个程序,每秒发布一个新的 marker,并以不同的形状依次替换上一个。

如果你想在阅读本教程后更全面地了解 marker 字段和对象类型,请参阅 Marker:显示类型。

从 visualization_tutorials 仓库 获取包,并在你的工作空间中构建。

Terminal window
$ colcon build --packages-select visualization_marker_tutorials

本教程的代码位于 visualization_marker_tutorials 包中。你可以在 basic_shapes.cpp 中阅读它。

下面逐段解析代码。

首先包含必要的头文件,包括 rclcpp 和 visualization_msgs/msg/Marker 消息定义。

#include <memory>
#include "rclcpp/logging.hpp"
#include "rclcpp/rclcpp.hpp"
#include "visualization_msgs/msg/marker.hpp"

这段代码应该已经很熟悉了。我们初始化 ROS 2,创建一个节点,并在 visualization_marker 话题上创建一个发布者。

rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("basic_shapes");
auto marker_pub = node->create_publisher<visualization_msgs::msg::Marker>(
"visualization_marker", 1);
rclcpp::Rate loop_rate(1);

到目前为止你应该已经熟悉 ROS 2 的头文件包含和节点设置。这里的关键是发布者:RViz 的 Marker 显示会订阅同一个话题。

这里我们创建一个整数来跟踪将要发布的形状。

uint32_t shape = visualization_msgs::msg::Marker::CUBE;

接下来是程序的核心部分。首先创建一个新的 visualization_msgs/msg/Marker 消息并逐项填充。消息头(header)设置了 marker 所属的坐标系和时间戳。

visualization_msgs::msg::Marker marker;
marker.header.frame_id = "my_frame";
marker.header.stamp = rclcpp::Clock().now();

命名空间(namespace)和 ID 字段组合在一起,为 marker 提供唯一标识。

marker.ns = "basic_shapes";
marker.id = 0;

type 字段指定我们发送的 marker 类型。

marker.type = shape;

action 字段指定对该 marker 执行的动作。

marker.action = visualization_msgs::msg::Marker::ADD;

接下来设置 marker 的位姿。

marker.pose.position.x = 0;
marker.pose.position.y = 0;
marker.pose.position.z = 0;
marker.pose.orientation.x = 0.0;
marker.pose.orientation.y = 0.0;
marker.pose.orientation.z = 0.0;
marker.pose.orientation.w = 1.0;

然后指定 marker 的缩放比例。

marker.scale.x = 1.0;
marker.scale.y = 1.0;
marker.scale.z = 1.0;

颜色以 RGBA 值指定,范围为 [0, 1]。

marker.color.r = 0.0f;
marker.color.g = 1.0f;
marker.color.b = 0.0f;
marker.color.a = 1.0;

lifetime 字段控制 marker 在自动删除之前的存活时长。

marker.lifetime = rclcpp::Duration::from_nanoseconds(0);

然后发布 marker 消息。

marker_pub->publish(marker);

以下代码通过循环切换 shape 变量,实现用一个 marker 消息依次展示四种形状。

switch (shape) {
case visualization_msgs::msg::Marker::CUBE:
shape = visualization_msgs::msg::Marker::SPHERE;
break;
case visualization_msgs::msg::Marker::SPHERE:
shape = visualization_msgs::msg::Marker::ARROW;
break;
case visualization_msgs::msg::Marker::ARROW:
shape = visualization_msgs::msg::Marker::CYLINDER;
break;
case visualization_msgs::msg::Marker::CYLINDER:
shape = visualization_msgs::msg::Marker::CUBE;
break;
}

休眠一秒后回到循环顶部。

loop_rate.sleep();
Terminal window
$ colcon build --packages-select visualization_marker_tutorials
Terminal window
$ source install/setup.bash
$ ros2 run visualization_marker_tutorials basic_shapes

现在节点已经开始发布 markers,启动 RViz 来查看它们。

Terminal window
$ source install/setup.bash
$ ros2 run rviz2 rviz2

如果你之前从未使用过 RViz,请先阅读 RViz 用户指南。

由于我们没有设置任何坐标变换,首先要做的是将 Fixed Frame 设置为 marker 消息中使用的坐标系 my_frame。然后添加一个 Marker 显示。注意,默认话题 visualization_marker 与节点发布的话题一致。

你现在应该能看到一个位于原点的 marker,它每秒切换一次形状。

基本形状教程

下一篇 marker 教程,请阅读 Marker:点和线。 如需了解 marker 消息的更多字段以及本文四种类型之外的其他 marker 类型,请阅读 Marker:显示类型。 完整的源代码树,请参见 visualization_tutorials 仓库。