rviz可视化Marker
ROS2 visualization_msgs::msg::Marker 使用指南
1. Marker 简介
visualization_msgs::msg::Marker
是 ROS2 中用于在 RViz 可视化各种图形(如点、线、面、模型等)的消息类型,用来表示一个单独的可视化对象(比如一个点、一条线、一个球体等)。通过发布 Marker 消息,可以在 RViz 中动态显示调试信息、地图、轨迹等。
2. 常用 Marker 类型
POINTS
:显示一组点LINE_STRIP
:显示一条折线LINE_LIST
:显示多条线段SPHERE
、CUBE
、CYLINDER
:显示几何体,分别为3D球体,立方体和圆柱体TRIANGLE_LIST
:显示三角面片SPHERE_LIST
:显示一组球体CUBE_LIST
:显示一组立方体CYLINDER_LIST
:显示一组圆柱体
3. 代码示例
以下代码展示了如何在 ROS2 中发布点云(POINTS 类型)的 Marker:
// 1. 包含必要的头文件
#include <rclcpp/rclcpp.hpp>
#include <visualization_msgs/msg/marker.hpp>
#include <visualization_msgs/msg/marker_array.hpp>
#include <geometry_msgs/msg/point.hpp>
// 2. 创建 Marker 消息
visualization_msgs::msg::Marker marker;
marker.header.frame_id = "map"; // 坐标系名称,需与 RViz 保持一致
marker.header.stamp = node->now(); // 时间戳
marker.ns = "example_points"; // 命名空间,可用于分组
marker.id = 0; // Marker 的唯一ID,同一ns下不能重复
marker.type = visualization_msgs::msg::Marker::POINTS; // Marker 类型:点云
marker.action = visualization_msgs::msg::Marker::ADD; // 动作:添加
// 3. 设置点的大小(宽和高,单位:米)
marker.scale.x = 0.2; // 点的宽度
marker.scale.y = 0.2; // 点的高度
marker.scale.z = 0.2; // 点的深度
// 对 POINTS 类型,marker.scale.z 无效
// 4. 设置点的颜色(RGBA,范围0~1)
marker.color.r = 1.0f; // 红色分量
marker.color.g = 0.0f; // 绿色分量
marker.color.b = 0.0f; // 蓝色分量
marker.color.a = 1.0f; // 透明度(1为不透明)
// 5. 添加点数据
geometry_msgs::msg::Point p1, p2;
p1.x = 1.0; p1.y = 2.0; p1.z = 0.0;
p2.x = 2.0; p2.y = 3.0; p2.z = 0.0;
marker.points.push_back(p1);
marker.points.push_back(p2);
// 6. 发布 Marker
visualization_msgs::msg::MarkerArray marker_array;
marker_array.markers.push_back(marker);
marker_pub->publish(marker_array);
详细注释说明
header.frame_id
:指定 Marker 所在的坐标系,RViz 必须有该坐标系。header.stamp
:时间戳,建议用node->now()
。ns
和id
:用于唯一标识一个 Marker,更新/删除时需一致。type
:Marker 的类型,决定显示方式。scale.x/y
:点的宽高,必须都大于 0。color
:点的颜色和透明度。points
:点的坐标列表。action
:常用为ADD
,也可用DELETE
删除。
4. 面色
有时需要将地图某一部分区域绘制出来,此时可以采用三角形“扇形剖分”的方式填充出来,将Marker
类型设置为TRIANGLE_LIST
,然后设置颜色进行显示。
**部分代码**
rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr map_area_markers_pub_ = this->create_publisher<visualization_msgs::msg::MarkerArray>("/map/map_area_markers", 10);
visualization_msgs::msg::MarkerArray map_area_marker_array;
if (polygon_points.size() >= 3)
{
visualization_msgs::msg::Marker fill_marker;
fill_marker.header.frame_id = "map";
fill_marker.header.stamp = this->now();
fill_marker.ns = "ad_area_fill";
fill_marker.type = visualization_msgs::msg::Marker::TRIANGLE_LIST;
fill_marker.action = visualization_msgs::msg::Marker::ADD;
fill_marker.id = id++;
fill_marker.scale.x = 1.0;
fill_marker.scale.y = 1.0;
fill_marker.scale.z = 1.0;
fill_marker.color.r = 0.0f;
fill_marker.color.g = 1.0f;
fill_marker.color.b = 0.0f;
fill_marker.color.a = 0.3f;
// 简单扇形三角剖分(以第一个点为中心)
const auto ¢er = polygon_points[0];
for (size_t i = 1; i + 1 < polygon_points.size(); ++i)
{
fill_marker.points.push_back(center);
fill_marker.points.push_back(polygon_points[i]);
fill_marker.points.push_back(polygon_points[i + 1]);
}
map_area_marker_array.markers.push_back(fill_marker);
}
map_area_markers_pub_.publish(map_area_marker_array)
5.常见问题
什么时候使用MarkerArray
- 当需要一次性发布多个可视化对象(比如一组点、一组线、多个不同的 marker)时,就用 MarkerArray,这样可以减少 topic 的数量和管理的复杂度。
点不显示?
- 检查
scale.x
和scale.y
是否都大于 0。
- 检查
- 检查
color.a
是否大于 0。 - 检查
frame_id
是否与 RViz 坐标系一致。 - 检查
points
是否有数据。
Marker 不更新?
ns
和id
必须与之前发布的一致,才能被覆盖。
RViz 没有显示?
- RViz 需添加
Marker
或MarkerArray
显示,并订阅正确的 topic。
- RViz 需添加