用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/MIUAV/vibe-coding-ros2 --skill marker-visualization命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | marker-visualization |
| description | RViz2 标记可视化技能 - Marker、MarkerArray、交互式标记配置 |
| argument-hint | rviz标记 OR 可视化标记 OR MarkerArray |
| user-invocable | true |
用于在 RViz2 中显示可视化标记
当需要以下帮助时使用此技能:
from visualization_msgs.msg import Marker, MarkerArray
import rospy
# 创建球体标记
marker = Marker()
marker.header.frame_id = "base_link"
marker.header.stamp = rospy.Time.now()
marker.ns = "my_markers"
marker.id = 0
marker.type = Marker.SPHERE
marker.action = Marker.ADD
marker.pose.position.x = 1.0
marker.pose.position.y = 0.0
marker.pose.position.z = 0.0
marker.pose.orientation.w = 1.0
marker.scale.x = 0.1
marker.scale.y = 0.1
marker.scale.z = 0.1
marker.color.r = 1.0
marker.color.g = 0.0
marker.color.b = 0.0
marker.color.a = 1.0
# 球体
marker.type = Marker.SPHERE
# 立方体
marker.type = Marker.CUBE
# 圆柱体
marker.type = Marker.CYLINDER
# 箭头
marker.type = Marker.ARROW
# 需要两点
marker.points.append(Point(0, 0, 0))
marker.points.append(Point(1, 0, 0))
# 线条
marker.type = Marker.LINE_STRIP
# 多个点
for i in range(10):
marker.points.append(Point(i*0.1, 0, 0))
# 线段列表
marker.type = Marker.LINE_LIST
# 三角形条带
marker.type = Marker.TRIANGLE_LIST
# 文本
marker.type = Marker.TEXT_VIEW_FACING
marker.text = "Hello World"
# 网格/模型
marker.type = Marker.MESH_RESOURCE
marker.mesh_resource = "package://robot/meshes/model.dae"
# 添加/更新标记
marker.action = Marker.ADD
# 删除标记
marker.action = Marker.DELETE
# 删除所有标记
marker.action = Marker.DELETEALL
# 删除命名空间中的所有标记
marker.ns = "my_markers"
marker.action = Marker.DELETE
# RGBA 颜色
marker.color.r = 1.0 # 红色 0-1
marker.color.g = 0.0
marker.color.b = 0.0
marker.color.a = 1.0 # 透明度 0-1
# 使用 ARGB 整数
marker.color.a = 1.0
marker.color.r = 1.0
marker.color.g = 0.5
marker.color.b = 0.0
# 缩放因子 (单位: 米)
marker.scale.x = 0.5 # 宽度
marker.scale.y = 0.5 # 高度/直径
marker.scale.z = 0.5 # 深度
# 箭头专用
marker.scale.x = 0.2 # 箭头杆直径
marker.scale.y = 0.1 # 箭头头部直径
marker.scale.z = 0.1 # 箭头头部长度
from visualization_msgs.msg import MarkerArray
marker_array = MarkerArray()
# 添加多个标记
for i in range(10):
marker = Marker()
marker.header.stamp = rospy.Time.now()
marker.header.frame_id = "map"
marker.ns = "waypoints"
marker.id = i
marker.type = Marker.SPHERE
marker.action = Marker.ADD
marker.pose.position.x = i * 1.0
marker.pose.position.y = 0
marker.pose.position.z = 0
marker.pose.orientation.w = 1.0
marker.scale.x = 0.2
marker.scale.y = 0.2
marker.scale.z = 0.2
marker.color.g = 1.0
marker.color.a = 1.0
marker_array.markers.append(marker)
# 发布
marker_pub.publish(marker_array)
# 只更新单个标记
def update_marker(index, position):
marker = Marker()
marker.header.frame_id = "map"
marker.header.stamp = rospy.Time.now()
marker.ns = "dynamic"
marker.id = index
marker.type = Marker.SPHERE
marker.action = Marker.ADD
marker.pose.position = position
marker.pose.orientation.w = 1.0
marker.scale.x = 0.1
marker.scale.y = 0.1
marker.scale.z = 0.1
marker.color.b = 1.0
marker.color.a = 1.0
publisher.publish(marker)
# 设置坐标系
marker.header.frame_id = "base_link" # 机器人基座
marker.header.frame_id = "map" # 地图坐标
marker.header.frame_id = "odom" # 里程计坐标
marker.header.frame_id = "world" # 世界坐标
# 设置时间戳
marker.header.stamp = rospy.Time.now() # 当前时间
marker.header.stamp = rospy.Time(0) # 始终为 0 表示永久
# 持续时间
marker.lifetime = rospy.Duration(5.0) # 显示 5 秒后消失
marker.lifetime = rospy.Duration() # 永久显示 (rospy.Duration() 表示 0)
from visualization_msgs.msg import InteractiveMarker, InteractiveMarkerControl, MenuEntry
# 创建交互式标记
interactive_marker = InteractiveMarker()
interactive_marker.header.frame_id = "base_link"
interactive_marker.header.stamp = rospy.Time.now()
interactive_marker.name = "my_interactive_marker"
interactive_marker.description = "Click me!"
# 添加控制
control = InteractiveMarkerControl()
control.name = "move_x"
control.orientation.w = 1
control.orientation.x = 1
control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS
interactive_marker.controls.append(control)
# 发布
interactive_marker_server.insert(interactive_marker)
interactive_marker_server.applyChanges()
# 移动轴
control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS
# 旋转轴
control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS
# 移动平面
control.interaction_mode = InteractiveMarkerControl.MOVE_PLANE
# 3D 移动
control.interaction_mode = InteractiveMarkerControl.MOVE_3D
# 3D 旋转
control.interaction_mode = InteractiveMarkerControl.ROTATE_3D
# 3D 移动和旋转
control.interaction_mode = InteractiveMarkerControl.FULL
from visualization_msgs.msg import MenuEntry
# 添加菜单
menu_entry = MenuEntry()
menu_entry.id = 1
menu_entry.label = "Option 1"
menu_entry.command = "option1"
interactive_marker.menu_entries.append(menu_entry)
menu_entry2 = MenuEntry()
menu_entry2.id = 2
menu_entry2.label = "Option 2"
menu_entry2.parent_id = 1 # 子菜单
interactive_marker.menu_entries.append(menu_entry2)
def processFeedback(feedback):
if feedback.event_type == InteractiveMarkerFeedback.MENU_SELECT:
if feedback.menu_entry_id == 1:
print("Option 1 selected")
elif feedback.menu_entry_id == 2:
print("Option 2 selected")
elif feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE:
print(f"New pose: {feedback.pose}")
interactive_marker_server.applyChanges()
server.setCallback(processFeedback)
from nav_msgs.msg import Path
# 从路径点创建线
marker = Marker()
marker.header.frame_id = "map"
marker.header.stamp = rospy.Time.now()
marker.type = Marker.LINE_STRIP
marker.action = Marker.ADD
for pose in path.poses:
point = Point()
point.x = pose.pose.position.x
point.y = pose.pose.position.y
point.z = pose.pose.position.z
marker.points.append(point)
marker.scale.x = 0.05 # 线宽
marker.color.b = 1.0
marker.color.a = 1.0
# 轨迹动画 (箭头)
trajectory_marker = Marker()
trajectory_marker.type = Marker.ARROW
trajectory_marker.action = Marker.ADD
for i, point in enumerate(trajectory_points):
arrow = Marker()
arrow.header.frame_id = "map"
arrow.header.stamp = rospy.Time.now()
arrow.id = i
arrow.type = Marker.ARROW
arrow.action = Marker.ADD
# 设置箭头位置和方向
...
解决方案:检查 frame_id 是否正确,确认时间戳不是未来时间
解决方案:确保每次更新使用相同的 ID 和 namespace