ROS中的Marker详解
Marker示例
在一开始的入门教程中,绘制了一个红色小球,在RViz中左右运动。这个示例由于直接用了Python脚本,且未采用urdf, xacro建模,所以看上去很不ROS。
然而,在打开rviz2后,通过【Add】->【By Topic】->【Marker】,却的确能够显示出圆形小球。而Marker,便是让这一切顺理成章的关键机制。
从本质上来说,Marker是用于在RViz中显示可视化图形和文本的特殊消息类型,尽管其定义的对象,不参与机器人的物理仿真,但在工程实践中,却是不可或缺的调试利器。下面在Python命令行中,做一个最简单的立方体

代码如下,如果打开rviz2后,看不到立方体,只需重新publish一下。
import rclpy
from visualization_msgs.msg import Marker
import time
# 初始化 ROS 2
rclpy.init()
# 创建一个节点对象(无需自定义类继承 Node)
node = rclpy.create_node('marker_test')
# 创建 Publisher
pub = node.create_publisher(Marker, '/test_marker', 10)
# 创建 Marker (蓝方块)
m = Marker()
m.header.frame_id = "map" # 注意:请确保 RViz 的 Fixed Frame 也是 map
m.header.stamp = node.get_clock().now().to_msg()
m.ns = "test"
m.id = 0
m.type = Marker.CUBE # 方块
m.action = Marker.ADD
m.pose.position.x = 2.0 # 在 map 坐标系前方 2 米处
m.pose.orientation.w = 1.0
m.scale.x = 0.3
m.scale.y = 0.3
m.scale.z = 0.3
m.color.b = 1.0 # 蓝色
m.color.a = 1.0 # 不透明
pub.publish(m)
m.color.r = 1.0
pub.publish(m) # 颜色改变
由于ROS底层是C++,所以务必注意,整型和浮点型不要搞错,小数点后面的0不能省略。
属性
从上面的示例可知,Marker的适用流程差不多分三步走,即创建Publisher->创建Marker->发布Marker,对应下面三行代码。
pub = node.create_publisher(Marker, '/test_marker', 10)
m = Marker()
pub.publish(m)
在实际工程中,一般采用面向对象,在Node的子类中创建并发布Marker,从而上面的node.create_publisher往往以self.create_publisher出现。
Marker在创建之后,可以继续声明其各种属性,包括
- 【header】包含坐标系(frame_id)和时间戳(stamp),在上述代码中,直接使用了全局地图坐标系map,并调用了节点的时钟。
- 【ns】和【id】即命名空间(namespace)和ID,二者构成Marker的身份表示,具有相同ns和id的Marker会新盖旧。
- 【type】形状类型(如球体、箭头等)。
- 【action】操作类型。可以是添加(ADD)、删除(DELETE)、删除全部(DELETEALL)。
- 【pose】位置(position)和姿态(orientation),决定图形画在空间中的哪里,朝向如何。
- 【scale】缩放比例,决定图形的大小(x, y, z方向的尺寸)。
- 【color】颜色设置,包括 RGBA 四个通道(红、绿、蓝、透明度,取值范围 0.0 ~ 1.0)。
- 【lifetime】存活时间。设为 0 表示永远存在,设为其他值(如 0.5秒)表示图形显示 0.5 秒后自动消失(常用于动态轨迹的拖尾效果)。
类型
Marker支持多种几何体,通过type和scale来控制其具体形状。type既可以是枚举值,也可以是整数,这也是C++祖传技能了,下表中括号里即为可选数值。
| 形状 | type | scale含义 |
|---|---|---|
| 箭头(0) | ARROW | x x x为线长; y y y为箭头尾部宽度; z z z为箭头头部宽度 |
| 长方体(1) | CUBE | x , y , z x,y,z x,y,z对应长宽高 |
| 椭球体(2) | SPHERE | x , y , z x,y,z x,y,z对应三轴直径 |
| 圆柱(3) | CYLINDER | x , y x,y x,y为底部椭圆长短轴; z z z为高 |
配合points数组,可以得到一些线和点的组合
| 形状 | type | scale含义 | points作用 |
|---|---|---|---|
| 折线(4) | LINE_STRIP | x x x控制线的粗细 | 连接points中的点 |
| 线段列表(5) | LINE_LIST | x x x控制线的粗细 | points中相邻两点构成一个线段 |
| 点集(6) | POINTS | x , y x,y x,y控制点的大小 |
Marker还支持一些高级图形,如下表所示
| 形状 | type | 关联属性 |
|---|---|---|
| 3D文本(9) | TEXT_VIEW_FACING | text设置显示的字符串;scale.z控制字体高度 |
| 3D模型(10) | MESH_RESOURCE | mesh_resource为模型文件的路径 |
| 三角形列表(11) | TRIANGLE_LIST | points中三个点一组,拼接成三角面 |
其中,外部3D文件支持.stl, .dae, .obj等,模型路径的格式通常为package://包名/meshes/xxx.stl,且可通过mesh_use_embedded_materials字段来控制是否使用模型自带的材质颜色。
下面新创建一个半透明的圆柱,同样用pub进行发布
m1 = Marker()
m1.header.frame_id = "map"
m1.header.stamp = node.get_clock().now().to_msg()
m1.ns = "test"
m1.id = 1
m1.type = Marker.CYLINDER
m1.action = Marker.ADD
m1.pose.position.x = 2.0
m1.pose.position.z = 1.0
m1.pose.orientation.w = 1.0
m1.scale.x = 0.5
m1.scale.y = 0.5
m1.scale.z = 2.5
m1.color.g = 1.0
m1.color.a = 0.3
pub.publish(m1)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)