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++祖传技能了,下表中括号里即为可选数值。

形状typescale含义
箭头(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数组,可以得到一些线和点的组合

形状typescale含义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_FACINGtext设置显示的字符串;scale.z控制字体高度
3D模型(10)MESH_RESOURCEmesh_resource为模型文件的路径
三角形列表(11)TRIANGLE_LISTpoints中三个点一组,拼接成三角面

其中,外部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)
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐