当前位置: 首页 > news >正文

ros三大核心消息包:geometry_msgs.msg、visualization_msgs、action_msgs.msg

一. geometry_msgs.msg(几何数据)

用途

机器人所有位置、姿态、速度、向量、坐标变换都用它。

1,基本消息:

1.1Point—— 3D 坐标点

作用:表示空间中的一个点(x,y,z)

float64 x float64 y float64 z

1.2Vector3—— 3D 向量

作用:表示方向 / 大小(平移、速度、缩放)

float64 x float64 y float64 z
  • 和 Point 结构一样,但语义不同
  • Vector3 表示方向 / 力 / 速度
  • Point 表示坐标位置

1.3Quaternion—— 四元数(姿态)

作用:表示 3D 旋转,无奇异值,ROS 标准姿态格式

float64 x float64 y float64 z float64 w
  • 必须是单位四元数
  • 默认无旋转:x=0,y=0,z=0,w=1

99% 的情况不用手动算,用tf_transformationspyquaternion库转换。

2,高级组合消息:

2.1Pose—— 位姿(位置 + 姿态)

Point position Quaternion orientation
  • 表示:在哪里 + 朝哪转
  • 用途:机器人位姿、目标点、物体位姿

2.2PoseStamped—— 带时间戳 + 坐标系的位姿

Header header Pose pose

Header 包含:

std_msgs/Header header uint32 seq time stamp string frame_id # 关键!坐标系
  • 必须带frame_id(如mapbase_linkodom
  • 导航、SLAM、TF 全都用这个

2.3Twist—— 速度(线速度 + 角速度)

控制小车移动的核心消息

Vector3 linear # 线速度 Vector3 angular # 角速度
  • linear.x:前进 / 后退
  • angular.z:左转 / 右转

2.4TwistStamped—— 带时间戳的速度

Header header Twist twist

2.5Transform—— 坐标变换

两个坐标系之间的平移 + 旋转

2.5 Transform —— 坐标变换 两个坐标系之间的平移 + 旋转

2.6TransformStamped—— 带坐标系的变换

Header header string child_frame_id Transform transform

3.最常用

消息作用最常用场景
Point3D 点坐标位置
Quaternion姿态旋转方向
Pose位置 + 姿态目标点
PoseStamped带坐标系位姿导航、SLAM
Twist速度小车控制
TransformStamped坐标变换TF、雷达 / 相机外参

二,visualization_msgs是 ROS 2 中专门用于 RViz 可视化的消息包

1. 核心消息详解

字段类型核心说明取值 / 示例
headerstd_msgs/Header坐标系 + 时间戳(必设)frame_id="map"stamp=当前时间
nsstring命名空间(分组管理)"waypoints""obstacles"
idint32唯一 ID(同 ns 下唯一)0、1、2... 用于区分同组内元素
typeint32元素类型(核心)见下文「类型枚举」
actionint32操作指令ADD=0(新增 / 修改)、DELETE=2(删除单个)、DELETEALL=3(删除整组)
posegeometry_msgs/Pose元素位姿(位置 + 朝向)position.x=1.0orientation.w=1.0(无旋转)
scalegeometry_msgs/Vector3尺寸缩放(单位:米)scale.x=0.3(立方体边长 0.3m)
colorstd_msgs/ColorRGBA颜色(RGBA,0~1)r=1.0,g=0.0,b=0.0,a=1.0(红色不透明)
lifetimebuiltin_interfaces/Duration生命周期(0 = 永久)Duration(5,0)(5 秒后自动消失)
frame_lockedbool是否锁定坐标系true(随坐标系移动)、false(固定位置)
pointsgeometry_msgs/Point[]顶点数组(部分类型必用)如折线、点云、三角形列表
textstring文字内容(TEXT 类型专用)"目标点"
mesh_resourcestring3D 模型路径(MESH 类型专用)"package://my_description/meshes/robot.dae"

「type」枚举(常用 8 类)

枚举值名称说明必用字段
0ARROW箭头(表示方向 / 路径)pose(起点 + 朝向)、scale(长度、半径)
1CUBE立方体posescale(长宽高)
2SPHERE球体posescale(半径)
3CYLINDER圆柱体posescale(半径、高度)
4LINE_STRIP折线(连续点连线)points(顶点列表)、scale(线宽)
9TEXT_VIEW_FACING面向相机文字posetextscale(文字大小)
10MESH_RESOURCE3D 模型posemesh_resourcescale
11TRIANGLE_LIST三角形面(复杂形状)points(3 个顶点 / 个三角形)
1.2MarkerArray(批量元素)
  • 定义Marker[] markers(多个 Marker 组成的数组)。
  • 优势:单次发布多个元素,减少通信开销,适合批量显示(如粒子云、多个障碍物)。
  • 用法:创建多个 Marker 加入markers数组,一次性发布到/markers话题。

2,示例:

2.1 Python 示例(RViz 显示红色立方体 + 文字箭头)
import rclpy from rclpy.node import Node from visualization_msgs.msg import Marker, MarkerArray from geometry_msgs.msg import Pose, Point, Quaternion class MarkerVisualizer(Node): def __init__(self): super().__init__('marker_visualizer') self.publisher_ = self.create_publisher(MarkerArray, '/visualization_markers', 10) self.timer = self.create_timer(1.0, self.publish_markers) # 每秒发布一次 def publish_markers(self): marker_array = MarkerArray() stamp = self.get_clock().now().to_msg() # 1. 红色立方体(ID=0) cube = Marker() cube.header.frame_id = "map" # 参考坐标系 cube.header.stamp = stamp cube.ns = "basic_shapes" cube.id = 0 cube.type = Marker.CUBE cube.action = Marker.ADD cube.pose = Pose(position=Point(x=1.0, y=0.0, z=0.5), orientation=Quaternion(w=1.0)) cube.scale.x = 0.6 # 边长0.6m cube.scale.y = 0.6 cube.scale.z = 1.0 cube.color.r = 1.0 # 红色 cube.color.g = 0.0 cube.color.b = 0.0 cube.color.a = 1.0 # 不透明 cube.lifetime = rclpy.Duration(seconds=0) # 永久显示 marker_array.markers.append(cube) # 2. 蓝色箭头(ID=1,指向立方体) arrow = Marker() arrow.header.frame_id = "map" arrow.header.stamp = stamp arrow.ns = "basic_shapes" arrow.id = 1 arrow.type = Marker.ARROW arrow.action = Marker.ADD arrow.pose = Pose(position=Point(x=0.0, y=0.0, z=0.5), orientation=Quaternion(w=1.0)) arrow.scale.x = 1.0 # 长度1m arrow.scale.y = 0.1 # 半径0.1m arrow.scale.z = 0.1 arrow.color.r = 0.0 arrow.color.g = 0.0 arrow.color.b = 1.0 arrow.color.a = 1.0 marker_array.markers.append(arrow) # 3. 绿色文字(ID=2,标注立方体) text = Marker() text.header.frame_id = "map" text.header.stamp = stamp text.ns = "basic_shapes" text.id = 2 text.type = Marker.TEXT_VIEW_FACING text.action = Marker.ADD text.pose = Pose(position=Point(x=1.0, y=0.0, z=1.2)) # 立方体上方 text.text = "目标物体" text.scale.z = 0.2 # 文字大小0.2m text.color.r = 0.0 text.color.g = 1.0 text.color.b = 0.0 text.color.a = 1.0 marker_array.markers.append(text) self.publisher_.publish(marker_array) self.get_logger().info("发布3个可视化标记") def main(args=None): rclpy.init(args=args) node = MarkerVisualizer() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
2.2 C++ 示例(批量发布点云折线)
#include "rclcpp/rclcpp.hpp" #include "visualization_msgs/msg/marker_array.hpp" #include "geometry_msgs/msg/point.hpp" using namespace std::chrono_literals; class MarkerArrayPublisher : public rclcpp::Node { public: MarkerArrayPublisher() : Node("marker_array_publisher") { publisher_ = this->create_publisher<visualization_msgs::msg::MarkerArray>("/visualization_markers", 10); timer_ = this->create_wall_timer(1s, std::bind(&MarkerArrayPublisher::publish_markers, this)); } private: void publish_markers() { auto marker_array = visualization_msgs::msg::MarkerArray(); auto stamp = this->get_clock()->now(); // 发布折线(ID=0,5个点) auto line_strip = visualization_msgs::msg::Marker(); line_strip.header.frame_id = "map"; line_strip.header.stamp = stamp; line_strip.ns = "path"; line_strip.id = 0; line_strip.type = visualization_msgs::msg::Marker::LINE_STRIP; line_strip.action = visualization_msgs::msg::Marker::ADD; line_strip.pose.orientation.w = 1.0; line_strip.scale.x = 0.05; // 线宽0.05m line_strip.color.r = 1.0; // 黄色 line_strip.color.g = 1.0; line_strip.color.b = 0.0; line_strip.color.a = 1.0; line_strip.lifetime = rclcpp::Duration(0); // 添加5个顶点(形成矩形路径) std::vector<std::pair<double, double>> points = {{0,0}, {2,0}, {2,1}, {0,1}, {0,0}}; for (auto [x, y] : points) { geometry_msgs::msg::Point p; p.x = x; p.y = y; p.z = 0.0; line_strip.points.push_back(p); } marker_array.markers.push_back(line_strip); publisher_->publish(marker_array); RCLCPP_INFO(this->get_logger(), "发布路径折线"); } rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr publisher_; rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MarkerArrayPublisher>()); rclcpp::shutdown(); return 0; }

3. 关键技巧与避坑

  1. 坐标系(frame_id)必设:错设会导致元素 “消失”,常见值:map(全局地图)、base_link(机器人本体)、odom(里程计)、laser_frame(雷达坐标系)。
  2. 颜色必须设 alpha(透明度):不设a=1.0可能导致完全透明看不见。
  3. 生命周期控制:临时标记设lifetime(如 5 秒),避免 RViz 残留;永久显示设0
  4. 批量用 MarkerArray:多个元素一次性发布,效率远高于多次发布单个 Marker。
  5. 删除元素:单个删除设action=DELETE+ns+id;整组删除设action=DELETEALL+ns
  6. 文字大小TEXT_VIEW_FACING仅通过scale.z控制大小,x/y无效。

三,action_msgs

action_msgs不是动作本身,而是所有 Action 通信的 “底层规则、状态、ID 管理”。

  • geometry_msgs:管位置
  • visualization_msgs:管 RViz 显示
  • action_msgs:管Action 通信的状态、目标 ID、取消机制

不包含业务数据(如目标点、速度、路径),只负责:

  1. 给每个任务发一个唯一 ID
  2. 告诉你任务当前状态(等待 / 运行 / 成功 / 失败 / 取消)
  3. 提供取消任务的服务

1. 它包含哪些内容?(官方完整定义)

action_msgs一共就3 个消息 + 1 个服务

1.1 GoalInfo.msg(目标身份证)

每个 Action 目标都会分配一个唯一 ID

unique_identifier_msgs/UUID goal_id # 唯一ID(一串随机码) builtin_interfaces/Time stamp # 时间戳

1.2 GoalStatus.msg(目标状态)

这是action_msgs 最重要的消息,表示任务当前处于什么状态。

GoalInfo goal_info int8 status # 状态常量 int8 STATUS_UNKNOWN = 0 int8 STATUS_ACCEPTED = 1 # 已接受 int8 STATUS_EXECUTING = 2 # 执行中 int8 STATUS_CANCELING = 3 # 正在取消 int8 STATUS_SUCCEEDED = 4 # 成功完成 int8 STATUS_ABORTED = 5 # 异常失败 int8 STATUS_CANCELED = 6 # 已取消 int8 STATUS_PENDING = 7 # 排队等待

状态机流程(最标准流程)

PENDING → ACCEPTED → EXECUTING → SUCCEEDED / ABORTED / CANCELED

1.3 GoalStatusArray.msg

发布多个目标的状态列表

GoalStatus[] status_list

1.4 CancelGoal.srv(取消目标服务)

请求:

客户端用来取消正在运行的任务

1.4 CancelGoal.srv(取消目标服务) 客户端用来取消正在运行的任务。

响应:

bool success GoalInfo[] canceled_goals

2. 为什么需要 action_msgs?

因为 Action 通信有 3 个特点:

  1. 长时任务(不是立刻完成)
  2. 可取消
  3. 有反馈、有结果、有状态

这些机制全部由 action_msgs 提供底层支持

http://www.jsqmd.com/news/564349/

相关文章:

  • QNX与Linux在嵌入式系统中的实时性与安全性对比
  • 千问3.5-2B图书馆管理:古籍封面图识别、分类号OCR与编目建议生成
  • C盘清理与优化:为本地运行Qwen3-ASR-0.6B模型释放足够磁盘空间
  • ST电机库FOC实战避坑:你的Clarke变换矩阵和ST官方一样吗?
  • 如何用GSE智能宏引擎解决魔兽世界技能管理难题?
  • OBS多平台直播同步解决方案:从配置到优化的完整指南
  • 北京联合丽格医疗美容(太阳宫院区)联系方式查询:如何通过官方渠道获取信息并做出审慎决策 - 品牌推荐
  • 高效查询!3秒实现手机号查QQ号的Python工具:轻量无依赖解决方案
  • Nat Commun | 首张糖尿病心梗的乳酰化修饰图谱揭示血管生成新机制
  • 如何突破物理控制器限制?ViGEmBus虚拟设备技术实战指南
  • 告别复杂配置!Z-Image-ComfyUI开箱即用,小白也能轻松生成高清人像
  • OCRmyPDF终极指南:如何让扫描PDF文件体积减半还能全文搜索?
  • PHP PhantomJS 安装与使用指南
  • 别再乱选转换芯片了!LT9211C、LT9211B对比与MIPI/LVDS/TTL互转换方案选型指南
  • SDMatte在C语言项目中的集成调用示例:轻量级嵌入式方案
  • ANIMATEDIFF PRO插件开发:JavaScript前端交互实现
  • Nunchaku-flux-1-dev参数详解:CFG Scale、种子数等关键参数实战影响
  • 硬触发vs软触发?大恒相机GXSDK开发中的5个关键选择(附OpenCV融合技巧)
  • 实测万物识别镜像:上传图片秒出结果,中文标签太友好了
  • 智能文献去重方案:彻底告别Zotero重复条目的实战策略
  • 网盘直链下载助手:如何一键获取真实下载链接,告别客户端限制?
  • HY-Motion 1.0生产环境:Blender插件集成与SMPLH骨骼输出实践
  • 别再手动组包了!STM32 + VOFA+ 的 JustFloat 协议,我封装了一个开箱即用的驱动库
  • 别再手动算脉冲了!用STM32的编码器接口模式(TIM_EncoderInterfaceConfig)实现电机测速,附完整代码
  • Word转HTML图片处理全攻略:Base64 vs 文件存储的实战对比
  • 终极Windows驱动管理指南:Driver Store Explorer高效释放30GB磁盘空间完整方案
  • M2LOrder情绪识别模型Python入门实战:快速部署与情感分析应用
  • SmallThinker-3B-Preview部署教程:边缘设备一键运行的保姆级指南
  • 在GCP上运行autoresearch
  • WarcraftHelper:如何解决魔兽争霸III兼容性与性能问题的完整开源方案