欢迎光临
我们一直在努力

ROS2 常见消息类型保姆级教程

目录

摘要

一、ROS2 消息类型到底是什么?

1.1 ROS2 节点之间靠消息通信

1.2 geometry_msgs::msg::Twist vel_cmd; 为什么这样写?

1.3 ROS2 消息类型的命名规则

1.4 如果想简写,可以使用 using

二、ROS2 里面常见消息类型分类

2.1 std_msgs:基础数据消息

(1)适合传递简单数据

(2)常见使用场景

2.2 geometry_msgs:几何运动相关消息

(1)机器人运动控制中非常常见

(2)常见消息含义表格总结

(3)geometry_msgs::msg::Twist 描述机器人速度

(4)geometry_msgs::msg::Pose 描述机器人位姿

(5)geometry_msgs::msg::PoseStamped 带时间戳和坐标系的位姿

(6)geometry_msgs::msg::Point 描述三维空间中的一个点

(7)geometry_msgs::msg::Quaternion 描述姿态和旋转

(8)geometry_msgs::msg::Vector3 描述三维向量

(9)geometry_msgs::msg::TransformStamped 描述两个坐标系之间的变换关系

2.3 nav_msgs:导航、定位、建图相关消息

(1)导航系统中经常出现

(2)常见消息含义

2.4 sensor_msgs:传感器相关消息

(1)雷达、IMU、相机、点云都在这里

(2)常见消息含义

三、总结

3.1 ROS2 消息类型整体总结

3.2 常见消息包对比表

3.3 geometry_msgs 常见消息对比表

3.4 geometry_msgs 一句话记忆表

3.5 常见坐标系对比表

3.6 常见 TF 关系总结表


摘要

在 ROS2 中,节点之间并不是直接传递 C++ 普通变量,而是通过 消息类型 Message 进行通信。比如控制机器人运动时,经常会看到:

geometry_msgs::msg::Twist vel_cmd;

这句代码的意思是:创建一个 ROS2 速度控制消息对象,用来描述机器人的线速度和角速度

本文将从这句代码出发,系统讲解 ROS2 中消息类型的命名规则、常见消息包、Twist 的内部结构、发布器写法、订阅器写法,以及如何在终端查看消息字段,帮助初学者真正看懂 ROS2 话题通信代码。


一、ROS2 消息类型到底是什么?

1.1 ROS2 节点之间靠消息通信

节点不是直接传变量,而是传消息

在普通 C++ 程序中,函数之间可以直接传递变量,比如:

int speed = 10;

但是 ROS2 是分布式机器人系统,通常会有多个节点同时运行,例如:

  • 键盘控制节点
  • 底盘控制节点
  • 雷达节点
  • 定位节点
  • 导航节点
  • 建图节点
  • 这些节点之间不能简单地通过普通变量通信,而是通过 ROS2 的通信机制传递数据

    最常见的方式就是:

    话题 Topic + 消息 Message

    例如:

    /cmd_vel

    这个话题通常用来发布机器人速度控制命令。

    它使用的消息类型一般是

    geometry_msgs::msg::Twist

    所以可以理解为:

    /cmd_vel 是话题名字
    geometry_msgs::msg::Twist 是话题里面传输的数据格式


    1.2 geometry_msgs::msg::Twist vel_cmd; 为什么这样写?

    它的本质是定义一个消息对象

    这句代码:

    geometry_msgs::msg::Twist vel_cmd;

    本质上和普通 C++ 变量定义类似。

    例如:

    int age;
    double speed;
    std::string name;

    对应到 ROS2 中就是:

    geometry_msgs::msg::Twist vel_cmd;

    可以拆成:

    消息类型  变量名;

    也就是:

    geometry_msgs::msg::Twist vel_cmd;

    其中:

    geometry_msgs::msg::Twist

    消息类型

    vel_cmd

    是自己定义的变量名


    1.3 ROS2 消息类型的命名规则

    一般格式是:功能包名::msg::消息名

    ROS2 C++ 中,消息类型一般采用下面这种格式:

    功能包名::msg::消息名

    例如:

    geometry_msgs::msg::Twist
    std_msgs::msg::String
    nav_msgs::msg::Odometry
    sensor_msgs::msg::LaserScan

    以:

    geometry_msgs::msg::Twist

    为例,可以拆成三部分:

  • geometry_msgs     // 消息所在的功能包
  • msg                         // 表示这是消息类型
  • Twist                       // 具体的消息名称
  • 所以:

    geometry_msgs::msg::Twist

    表示:

    geometry_msgs 功能包下面的 Twist 消息类型

    这也是为什么不能随便写成:

    Twist vel_cmd;

    因为编译器默认并不知道 Twist 是谁,必须告诉它这个类型来自哪里。


    1.4 如果想简写,可以使用 using

    初学 ROS2 时,最推荐写完整形式:

    geometry_msgs::msg::Twist vel_cmd;

    这种写法虽然长一点,但是含义最清楚。

    如果后面代码中频繁使用,也可以写:

    using geometry_msgs::msg::Twist;

    Twist vel_cmd;

    或者写成类型别名:

    using TwistMsg = geometry_msgs::msg::Twist;

    TwistMsg vel_cmd;

    不过在学习阶段,建议先保持完整写法,这样更容易理解消息来自哪个功能包。


    二、ROS2 里面常见消息类型分类

    2.1 std_msgs:基础数据消息

    (1)适合传递简单数据

    std_msgs 可以理解为 ROS2 中比较基础的一类消息,常用于传递字符串、整数、浮点数、布尔值等简单数据。

    常见类型如下:

    std_msgs::msg::String
    std_msgs::msg::Int32
    std_msgs::msg::Float64
    std_msgs::msg::Bool

    例如定义一个字符串消息:

    std_msgs::msg::String msg;
    msg.data = "hello ros2";

    其中:

    msg.data

    才是真正保存字符串内容的字段。

    (2)常见使用场景

    std_msgs 常用于一些简单话题,例如:

  • 发布一个开关状态
  • 发布一个计数值
  • 发布一段字符串提示
  • 发布一个简单的控制标志
  • 例如:

    std_msgs::msg::Bool flag;
    flag.data = true;

    表示发布一个布尔类型消息。


    2.2 geometry_msgs:几何运动相关消息

    (1)机器人运动控制中非常常见

    geometry_msgs 是机器人开发中非常核心的一类消息,主要用于描述:

  • 速度
  • 位置
  • 姿态
  • 坐标点
  • 坐标变换
  • 常见类型如下:

    geometry_msgs::msg::Twist
    geometry_msgs::msg::Pose
    geometry_msgs::msg::PoseStamped
    geometry_msgs::msg::Point
    geometry_msgs::msg::Quaternion
    geometry_msgs::msg::Vector3
    geometry_msgs::msg::TransformStamped


    (2)常见消息含义表格总结

    消息类型主要作用
    Twist 描述速度,包括线速度和角速度
    Pose 描述位姿,包括位置和姿态
    PoseStamped 带时间戳和坐标系的位姿
    Point 三维空间点坐标
    Quaternion 四元数姿态
    Vector3 三维向量
    TransformStamped 坐标系之间的变换关系
    消息类型主要作用核心字段常见场景
    Twist 描述速度 linear、angular /cmd_vel 速度控制
    Pose 描述位姿 position、orientation 机器人当前位置、目标位姿
    PoseStamped 带时间和坐标系的位姿 header、pose 导航目标、路径点、定位结果
    Point 描述空间点 x、y、z 目标点、障碍物点、坐标点
    Quaternion 描述姿态旋转 x、y、z、w 机器人朝向、坐标旋转
    Vector3 描述三维向量 x、y、z 速度、角速度、加速度、方向量
    TransformStamped 描述坐标系变换 header、child_frame_id、transform TF 坐标变换

    (3)geometry_msgs::msg::Twist 描述机器人速度

    Twist 用来描述机器人的运动速度,通常用于控制机器人底盘运动,最常见的话题是:

    /cmd_vel

    它里面包含两部分:

    Vector3 linear // 线速度
    Vector3 angular // 角速度

    完整字段是:

    vel_cmd.linear.x
    vel_cmd.linear.y
    vel_cmd.linear.z

    vel_cmd.angular.x
    vel_cmd.angular.y
    vel_cmd.angular.z

    对于大多数地面移动机器人,最常用的是:

    vel_cmd.linear.x // 前进 / 后退速度
    vel_cmd.angular.z // 左转 / 右转角速度

    例如:

    geometry_msgs::msg::Twist vel_cmd;

    vel_cmd.linear.x = 0.2;
    vel_cmd.angular.z = 0.0;

    表示机器人以 0.2 m/s 向前运动,不旋转。

    如果写成:

    vel_cmd.linear.x = 0.0;
    vel_cmd.angular.z = 0.5;

    表示机器人不前进,只进行原地旋转。

    所以 Twist 可以理解为:

    Twist = 线速度 + 角速度


    (4)geometry_msgs::msg::Pose 描述机器人位姿

    Pose 用来描述一个物体或者机器人在空间中的 位置和姿态。

    它包含两部分:

    Point position // 位置
    Quaternion orientation // 姿态

    完整字段是:

    pose.position.x
    pose.position.y
    pose.position.z

    pose.orientation.x
    pose.orientation.y
    pose.orientation.z
    pose.orientation.w

    其中:

    position

    表示位置,也就是机器人在哪里。

    orientation

    表示姿态,也就是机器人朝向哪里。

    例如:

    geometry_msgs::msg::Pose pose;

    pose.position.x = 1.0;
    pose.position.y = 2.0;
    pose.position.z = 0.0;

    pose.orientation.w = 1.0;

    表示机器人位于:

    x = 1.0
    y = 2.0
    z = 0.0

    姿态使用四元数表示。

    对于二维移动机器人来说,通常重点关注:

    pose.position.x
    pose.position.y
    pose.orientation

    因为地面机器人一般在平面上运动,z 方向变化较少。


    (5)geometry_msgs::msg::PoseStamped 带时间戳和坐标系的位姿

    PoseStamped 可以理解为:

    PoseStamped = Header + Pose

    也就是在 Pose 的基础上增加了时间戳坐标系信息

    它的结构大概是:

    std_msgs::msg::Header header
    geometry_msgs::msg::Pose pose

    常用字段有:

    pose_stamped.header.stamp
    pose_stamped.header.frame_id

    pose_stamped.pose.position.x
    pose_stamped.pose.position.y
    pose_stamped.pose.position.z

    pose_stamped.pose.orientation.x
    pose_stamped.pose.orientation.y
    pose_stamped.pose.orientation.z
    pose_stamped.pose.orientation.w

    其中:

    header.stamp

    表示这个位姿对应的时间

    header.frame_id

    表示这个位姿属于哪个坐标系

    例如:

    geometry_msgs::msg::PoseStamped target_pose;

    target_pose.header.frame_id = "map";
    target_pose.header.stamp = this->now();

    target_pose.pose.position.x = 3.0;
    target_pose.pose.position.y = 2.0;
    target_pose.pose.orientation.w = 1.0;

    表示:

    机器人目标点在 map 坐标系下,位置是 (3.0, 2.0)。

    PoseStamped 在导航里面非常常见,例如:

  • 目标点
  • 路径点
  • 定位结果
  • 导航目标
  • 相比 Pose,PoseStamped 更完整,因为它说明了:

    这个位姿是什么时候的?
    这个位姿属于哪个坐标系?


    (6)geometry_msgs::msg::Point 描述三维空间中的一个点

    Point 用来表示三维空间中的一个坐标点

    它只有三个字段:

    point.x
    point.y
    point.z

    例如:

    geometry_msgs::msg::Point point;

    point.x = 1.0;
    point.y = 2.0;
    point.z = 0.0;

    表示空间中的一个点:

    (1.0, 2.0, 0.0)

    Point 常用于:

  • 表示目标点
  • 表示机器人位置
  • 表示路径中的某个点
  • 表示障碍物位置
  • 表示三维空间坐标
  • 需要注意的是,Point 只表示位置,不表示朝向。

    也就是说:

  • Point 只能说明在哪里
  • Pose 可以说明在哪里 + 朝向哪里

  • (7)geometry_msgs::msg::Quaternion 描述姿态和旋转

    Quaternion 用来描述三维空间中的姿态,也就是物体的朝向。

    它包含四个字段:

    quaternion.x
    quaternion.y
    quaternion.z
    quaternion.w

    例如:

    geometry_msgs::msg::Quaternion q;

    q.x = 0.0;
    q.y = 0.0;
    q.z = 0.0;
    q.w = 1.0;

    通常表示没有旋转,也就是默认朝向。

    在机器人中,姿态有很多表示方式,比如:

  • 欧拉角:roll、pitch、yaw
  • 四元数:x、y、z、w
  • ROS2 中很多消息默认使用四元数表示姿态,例如:

    Pose.orientation
    Odometry.pose.pose.orientation
    TransformStamped.transform.rotation

    对于地面移动机器人来说,最常关心的是 yaw,也就是绕 z 轴的旋转角。

    但是在 ROS2 消息中,通常不是直接存 yaw,而是存成四元数

    orientation.x
    orientation.y
    orientation.z
    orientation.w

    所以实际开发中,经常需要在:

    yaw 角

    和:

    Quaternion 四元数

    之间进行转换。


    (8)geometry_msgs::msg::Vector3 描述三维向量

    Vector3 用来描述三维向量,包含三个字段:

    vector.x
    vector.y
    vector.z

    例如:

    geometry_msgs::msg::Vector3 vec;

    vec.x = 1.0;
    vec.y = 0.0;
    vec.z = 0.0;

    它看起来和 Point 很像,都是:

    x
    y
    z

    但是含义不一样。

    Point 表示一个空间位置:

    我在哪里?

    Vector3 表示一个方向量或物理量:

  • 往哪个方向?
  • 速度是多少?
  • 加速度是多少?
  • 角速度是多少?
  • 比如 Twist 里面就用到了 Vector3:

    geometry_msgs::msg::Twist vel_cmd;

    vel_cmd.linear.x = 0.2;
    vel_cmd.angular.z = 0.5;

    这里的:

    linear
    angular

    本质上都是 Vector3 类型。

    所以:

    Twist.linear.x
    Twist.angular.z

    能够成立,是因为 linear 和 angular 都是 Vector3。


    (9)geometry_msgs::msg::TransformStamped 描述两个坐标系之间的变换关系

    TransformStamped 用来描述一个坐标系到另一个坐标系之间的关系。

    它可以理解为:

    TransformStamped = Header + child_frame_id + Transform

    常见结构如下:

    header.stamp
    header.frame_id
    child_frame_id

    transform.translation.x
    transform.translation.y
    transform.translation.z

    transform.rotation.x
    transform.rotation.y
    transform.rotation.z
    transform.rotation.w

    其中:

    header.frame_id

    表示父坐标系

    child_frame_id

    表示子坐标系

    transform.translation

    表示两个坐标系之间的位置偏移

    transform.rotation

    表示两个坐标系之间的旋转关系

    例如:

    geometry_msgs::msg::TransformStamped transform;

    transform.header.stamp = this->now();
    transform.header.frame_id = "odom";
    transform.child_frame_id = "base_link";

    transform.transform.translation.x = 1.0;
    transform.transform.translation.y = 2.0;
    transform.transform.translation.z = 0.0;

    transform.transform.rotation.w = 1.0;

    这表示:

    base_link 坐标系

    相对于:

    odom 坐标系

    的位置偏移是:

    x = 1.0
    y = 2.0
    z = 0.0

    TransformStamped 在 TF 坐标变换中非常重要,常见坐标系对比表如下:

    坐标系名称中文理解主要含义是否跟机器人一起动常见来源 / 发布者常见用途
    map 地图坐标系 / 全局坐标系 表示机器人在整张地图中的全局位置 不跟机器人动,通常固定在地图上 SLAM、AMCL、定位系统、导航系统 全局定位、全局路径规划、导航目标点
    odom 里程计坐标系 表示机器人从启动位置开始,通过里程计连续推算出来的位置 不跟机器人一起动,但以启动附近为参考 轮式里程计、视觉里程计、IMU 融合、机器人底盘 短时间连续定位、局部运动控制、速度估计
    base_link 机器人本体坐标系 表示机器人自身的坐标系,通常固定在机器人底盘中心 跟机器人一起移动和旋转 机器人 URDF、底盘模型、TF 发布器 描述机器人自身位置、速度方向、传感器安装位置
    laser 激光雷达坐标系 表示激光雷达自身的坐标系 跟机器人一起动,因为雷达安装在机器人上 激光雷达驱动、静态 TF 描述 /scan 雷达数据、障碍物检测、建图导航
    camera_link 相机坐标系 表示相机本体或相机安装位置的坐标系 跟机器人一起动,因为相机安装在机器人上 相机驱动、深度相机驱动、静态 TF 图像、深度图、点云、视觉识别
    imu_link IMU 坐标系 表示 IMU 传感器自身的坐标系 跟机器人一起动,因为 IMU 安装在机器人上 IMU 驱动、静态 TF 姿态估计、角速度、线加速度、惯性导航
    TF 关系含义说明
    map -> odom 地图坐标系到里程计坐标系的变换 通常由定位系统发布,用来修正里程计漂移
    odom -> base_link 里程计坐标系到机器人本体坐标系的变换 通常由里程计发布,表示机器人连续运动位置
    base_link -> laser 机器人本体到激光雷达的安装关系 通常是静态 TF,表示雷达装在机器人哪个位置
    base_link -> camera_link 机器人本体到相机的安装关系 通常是静态 TF,表示相机装在机器人哪个位置
    base_link -> imu_link 机器人本体到 IMU 的安装关系 通常是静态 TF,表示 IMU 装在机器人哪个位置

    这些坐标系之间的关系,通常就是通过 TransformStamped 发布出去的。


    2.3 nav_msgs:导航、定位、建图相关消息

    (1)导航系统中经常出现

    nav_msgs 主要用于机器人导航、定位、路径规划、地图构建等任务。

    常见类型如下:

    nav_msgs::msg::Odometry
    nav_msgs::msg::Path
    nav_msgs::msg::OccupancyGrid

    (2)常见消息含义

    消息类型主要作用
    Odometry 里程计信息,包括机器人位姿和速度
    Path 路径信息,由一串位姿点组成
    OccupancyGrid 栅格地图,常用于 SLAM 和导航

    例如:

    nav_msgs::msg::Odometry odom;

    Odometry 里面通常包含两类核心信息:

    pose // 机器人当前位姿
    twist // 机器人当前速度

    也就是说,里程计消息不仅可以描述机器人现在在哪里,还可以描述机器人当前运动速度是多少。


    2.4 sensor_msgs:传感器相关消息

    (1)雷达、IMU、相机、点云都在这里

    sensor_msgs 主要用于传递传感器数据。

    常见类型如下:

    sensor_msgs::msg::LaserScan
    sensor_msgs::msg::Imu
    sensor_msgs::msg::Image
    sensor_msgs::msg::PointCloud2
    sensor_msgs::msg::JointState
    sensor_msgs::msg::NavSatFix

    (2)常见消息含义

    消息类型主要作用
    LaserScan 二维激光雷达数据
    Imu IMU 数据,包括角速度、线加速度、姿态等
    Image 相机图像数据
    PointCloud2 点云数据,常用于 3D 激光雷达
    JointState 关节状态,机械臂、轮子编码器都可能用到
    NavSatFix GPS 定位数据

    例如:

    sensor_msgs::msg::LaserScan scan;

    通常用于二维激光雷达话题,例如:

    /scan

    而:

    sensor_msgs::msg::Imu imu;

    通常用于 IMU 话题,例如:

    /imu


    三、总结

    3.1 ROS2 消息类型整体总结

    在 ROS2 中,节点之间并不是直接传递普通 C++ 变量,而是通过 消息类型 Message 进行通信。

    比如:

    geometry_msgs::msg::Twist vel_cmd;

    这句代码的意思是:

    创建一个 geometry_msgs 功能包下的 Twist 消息对象,变量名叫 vel_cmd。

    它可以拆成:

    部分含义
    geometry_msgs 消息所在功能包
    msg 表示这是消息类型
    Twist 具体消息名称
    vel_cmd 自己定义的消息对象名

    ROS2 中常见消息类型通常采用下面这种格式:

    功能包名::msg::消息名 变量名;

    例如:

    std_msgs::msg::String msg;
    geometry_msgs::msg::Twist vel_cmd;
    nav_msgs::msg::Odometry odom;
    sensor_msgs::msg::LaserScan scan;


    3.2 常见消息包对比表

    消息包中文理解主要作用常见消息
    std_msgs 基础数据消息 传递简单数据,例如字符串、整数、小数、布尔值 String、Int32、Float64、Bool
    geometry_msgs 几何运动消息 描述速度、位置、姿态、坐标点、坐标变换 Twist、Pose、PoseStamped、Point、Quaternion、Vector3、TransformStamped
    nav_msgs 导航相关消息 描述里程计、路径、地图等导航信息 Odometry、Path、OccupancyGrid
    sensor_msgs 传感器消息 描述雷达、IMU、相机、点云、GPS 等传感器数据 LaserScan、Imu、Image、PointCloud2、JointState、NavSatFix

    3.3 geometry_msgs 常见消息对比表

    消息类型中文理解核心组成常见字段常见用途
    Twist 速度消息 线速度 + 角速度 linear、angular /cmd_vel 速度控制
    Pose 位姿消息 位置 + 姿态 position、orientation 机器人当前位置、目标位姿
    PoseStamped 带时间戳和坐标系的位姿 Header + Pose header、pose 导航目标点、路径点、定位结果
    Point 三维空间点 x、y、z 坐标 x、y、z 目标点、障碍物点、路径点
    Quaternion 四元数姿态 x、y、z、w x、y、z、w 描述机器人朝向、坐标旋转
    Vector3 三维向量 x、y、z 分量 x、y、z 速度、角速度、加速度、方向量
    TransformStamped 坐标系变换 时间戳 + 父子坐标系 + 平移旋转 header、child_frame_id、transform TF 坐标变换

    3.4 geometry_msgs 一句话记忆表

    消息类型一句话理解
    Twist 描述机器人怎么运动,也就是速度
    Pose 描述机器人在哪里、朝向哪里
    PoseStamped 描述机器人在某个时间、某个坐标系下的位姿
    Point 只描述一个点在哪里
    Quaternion 描述物体或机器人朝向哪里
    Vector3 描述一个三维方向量或物理量
    TransformStamped 描述两个坐标系之间的位置和旋转关系

    3.5 常见坐标系对比表

    坐标系中文理解是否跟机器人一起动主要作用
    map 地图坐标系 / 全局坐标系 不跟机器人动 全局定位、全局路径规划、导航目标点
    odom 里程计坐标系 不跟机器人一起动,但会随着里程计连续推算 短时间连续定位、局部运动控制
    base_link 机器人本体坐标系 跟机器人一起移动和旋转 描述机器人自身位置、速度方向、传感器安装基准
    laser 激光雷达坐标系 跟机器人一起动 描述激光雷达数据、障碍物检测
    camera_link 相机坐标系 跟机器人一起动 图像、深度图、点云、视觉识别
    imu_link IMU 坐标系 跟机器人一起动 姿态估计、角速度、线加速度

    3.6 常见 TF 关系总结表

    TF 关系含义常见发布者
    map -> odom 地图坐标系到里程计坐标系的变换 SLAM、AMCL、定位系统
    odom -> base_link 里程计坐标系到机器人本体坐标系的变换 轮式里程计、视觉里程计、底盘节点
    base_link -> laser 机器人本体到激光雷达的安装关系 静态 TF、URDF
    base_link -> camera_link 机器人本体到相机的安装关系 静态 TF、URDF
    base_link -> imu_link 机器人本体到 IMU 的安装关系 静态 TF、URDF

    这些坐标系之间的关系,通常就是通过:

    geometry_msgs::msg::TransformStamped

    发布出去的。

    赞(0)
    未经允许不得转载:171主机测评 » ROS2 常见消息类型保姆级教程
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址