news 2026/5/14 18:50:10

【ROS2速成 - Day2】ROS2五大核心概念吃透(嵌入式类比记忆,超好懂)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【ROS2速成 - Day2】ROS2五大核心概念吃透(嵌入式类比记忆,超好懂)

前言

大家好,我是深耕嵌入式 15 年的老林。上一篇 Day1 我们搭好了 ROS2 的开发环境,很多同学私信我说,ROS2 的概念太多了,什么节点、话题、服务,听着就头大,完全不知道和我们平时写单片机代码有什么关系。

其实我刚开始学 ROS2 的时候也有同样的感觉,觉得这东西太 "上层" 了,和我们天天写的寄存器操作、任务调度、串口通信完全是两个世界。但后来我发现,ROS2 的核心设计思想和嵌入式开发是完全相通的,只是换了一套名词而已

今天这篇文章,我就用嵌入式工程师最熟悉的语言,把 ROS2 的五大核心组件全部翻译过来。看完你会发现,原来 ROS2 这么简单,就是把我们嵌入式里天天用的东西,封装成了一套标准的框架而已。


一、核心思想:ROS2 就是一个分布式的嵌入式操作系统

先给大家建立一个整体认知:ROS2 本质上就是一个分布式的、跨平台的嵌入式操作系统

  • 我们平时用的 FreeRTOS 是单芯片的操作系统,管理同一个 MCU 上的多个任务
  • ROS2 是跨设备的操作系统,管理同一个网络上的多个节点(可以是 PC、单片机、树莓派、机器人)

所有的 ROS2 程序,都是围绕着 "节点之间如何通信" 这个核心问题展开的。而通信的方式,就是我们今天要讲的话题、服务、参数。


二、五大核心组件详解(嵌入式类比记忆法)

2.1 节点 (Node) = FreeRTOS 独立任务线程

最核心的类比:一个 ROS2 节点,就相当于 FreeRTOS 里用 xTaskCreate 创建的一个独立任务。

我们写嵌入式代码的时候都知道:

  • 不能把所有功能都写在 main 函数的 while (1) 里,那样耦合度太高,出了问题不好排查
  • 我们会把不同的功能拆成不同的任务:比如一个任务负责采集传感器数据,一个任务负责电机控制,一个任务负责串口通信
  • 每个任务有自己的栈空间,独立运行,互不干扰
  • 任务之间通过消息队列、信号量等方式通信

ROS2 的节点就是完全一样的设计思想:

  • 一个节点只负责一个功能:比如camera_node负责采集摄像头数据,imu_node负责采集 IMU 数据,motor_control_node负责控制电机
  • 每个节点是一个独立的进程,有自己的内存空间,独立运行,崩溃了不会影响其他节点
  • 节点可以运行在同一个设备上,也可以运行在不同的设备上(比如树莓派跑传感器节点,PC 跑路径规划节点)
  • 节点之间通过话题、服务、参数等方式通信

举个例子:一个最简单的差分驱动机器人,至少需要 3 个节点:

  1. imu_node:采集 IMU 数据,发布 IMU 话题
  2. motor_driver_node:订阅速度话题,控制电机转动
  3. teleop_node:接收键盘输入,发布速度话题

这就相当于我们在 FreeRTOS 里创建了 3 个任务,每个任务做一件事,通过消息队列传递数据。

2.2 话题 (Topic) = 消息队列 + 串口广播

最核心的类比:一个 ROS2 话题,就相当于一个带广播功能的消息队列,或者说一个串口总线。

我们先回忆一下嵌入式里的消息队列:

  • 一个任务往消息队列里发数据(生产者)
  • 一个或多个任务从消息队列里取数据(消费者)
  • 异步通信:发完就走,不用等对方接收
  • 数据是先进先出的

再回忆一下串口广播:

  • 一个设备往串口总线上发数据
  • 所有挂在总线上的设备都能收到这个数据
  • 谁需要谁处理,不需要的可以忽略

ROS2 的话题,就是把这两个东西结合起来了:

  • 有一个 ** 发布者 (Publisher)** 往话题里发消息(相当于往消息队列里写数据,或者往串口总线上发数据)
  • 有一个或多个 ** 订阅者 (Subscriber)** 从话题里收消息(相当于从消息队列里读数据,或者监听串口总线)
  • 异步通信:发布者发完消息就继续干自己的事,不用等订阅者处理
  • 一对多通信:一个发布者可以对应多个订阅者
  • 数据是先进先出的

举个例子:上面的teleop_node/cmd_vel话题里发布速度消息,motor_driver_node订阅这个话题,收到消息后控制电机转动。如果我们再加一个odometry_node,也订阅/cmd_vel话题,就可以根据速度计算机器人的里程计。

这就相当于teleop_task往一个消息队列里发速度数据,motor_control_taskodometry_task都从这个消息队列里取数据。

注意:话题的命名很重要,就像串口的设备名/dev/ttyUSB0一样,只有发布者和订阅者使用完全相同的话题名,才能通信。

2.3 消息 (Message) = C 语言通信结构体

最核心的类比:一个 ROS2 消息,就相当于我们在 C 语言里定义的一个通信结构体。

这个类比绝对是 ROS2 入门最重要的一个点,理解了这个,你就理解了 ROS2 通信的本质。

我们写嵌入式代码的时候,两个任务之间要传递数据,或者两个设备之间通过串口通信,会怎么做?

  • 我们会先定义一个结构体,约定好数据的格式:比如第 1 个字节是命令字,第 2-3 个字节是速度,第 4-5 个字节是角度
  • 发送方把数据打包成这个结构体,然后发送出去
  • 接收方按照同样的结构体格式解析数据

如果双方约定的结构体不一样,就会解析出乱码,通信失败。这是我们写嵌入式代码天天都会遇到的问题。

ROS2 的消息,就是帮你把这个 "约定结构体" 的过程标准化了。ROS2 已经预定义了大量常用的消息类型,你直接用就行,不用自己再去定义协议了。

举个例子:最常用的速度消息geometry_msgs/Twist,它的结构体定义是这样的:

// 对应C语言的结构体 typedef struct Twist { Vector3 linear; // 线速度,单位m/s Vector3 angular; // 角速度,单位rad/s } Twist; typedef struct Vector3 { float x; float y; float z; } Vector3;

对于差分驱动机器人来说,我们只需要用linear.x(前后速度)和angular.z(转向速度)就够了。

teleop_node/cmd_vel话题发布一个Twist消息时,就相当于它把一个这样的结构体打包发了出去。motor_driver_node收到这个结构体后,解析出linear.xangular.z的值,然后转换成左右轮的 PWM 输出。

就是这么简单!没有任何魔法,就是结构体的打包和解包而已。

2.4 服务 (Service) = 函数调用 + 串口问答

最核心的类比:一个 ROS2 服务,就相当于一个远程函数调用,或者说串口的问答式通信。

我们先回忆一下函数调用:

  • 你调用一个函数,传入参数
  • 函数执行相应的操作
  • 函数返回一个结果给你

再回忆一下串口的问答式通信:

  • 你给设备发一个指令:"请读取传感器 A 的值"
  • 设备收到指令后,读取传感器的值
  • 设备给你回复:"传感器 A 的值是 123"

这两种都是同步通信:你发完请求后,必须等对方回复,才能继续往下执行。

ROS2 的服务,就是这种同步的、一对一的通信方式:

  • 有一个 ** 客户端 (Client)** 发送请求(相当于调用函数,传入参数)
  • 有一个 ** 服务端 (Server)** 处理请求,执行相应的操作
  • 服务端给客户端返回一个响应(相当于函数的返回值)
  • 一对一通信:一个服务端只能同时处理一个客户端的请求
  • 同步通信:客户端发完请求后会阻塞,直到收到响应

举个例子:我们想让机器人执行一个拍照的操作,就可以用服务来实现:

  1. 客户端发送请求:"请拍一张照片"
  2. 服务端(摄像头节点)收到请求后,控制摄像头拍照
  3. 服务端返回响应:"拍照成功,照片数据是 xxx"

话题 vs 服务 怎么选?

通信方式适用场景嵌入式类比
话题连续不断的数据流消息队列、串口广播
服务一次性的、有返回值的操作函数调用、串口问答

简单来说:一直发的用话题,偶尔问的用服务

2.5 参数 (Parameter) = 全局变量 + Flash 配置参数

最核心的类比:ROS2 参数,就相当于嵌入式里的全局变量,或者存在 Flash 里的配置参数。

我们写嵌入式代码的时候,经常会用到一些配置参数:比如电机的 PID 参数、传感器的校准值、串口的波特率。这些参数我们会:

  • 定义成全局变量,程序运行时可以读写
  • 保存在 Flash 里,掉电不丢失
  • 可以通过串口指令修改,不用重新烧写程序

ROS2 的参数,就是实现了这个功能:

  • 参数是节点的配置项,以键值对的形式存在(比如"motor_pid_p": 1.0
  • 节点运行时可以读写自己的参数
  • 参数可以保存在 YAML 文件里,启动节点时加载
  • 可以通过命令行或其他节点修改参数,不用重新编译代码

举个例子:我们的motor_control_node可以定义三个参数:pid_ppid_ipid_d。启动节点时从配置文件加载这些参数,运行时如果发现 PID 参数不合适,可以直接通过命令行修改,不用重新编译代码,非常方便。


三、ROS2 常用基础消息类型(必须熟记)

ROS2 已经为我们预定义了大量常用的消息类型,覆盖了机器人开发的绝大多数场景。下面这几个是你开发中天天都会用到的,必须熟记。

3.1 基础数据类型 (std_msgs)

最基础的消息类型,封装了 C 语言的基本数据类型:

  • std_msgs/String:字符串消息,最常用的调试消息
    string data
  • std_msgs/Int32std_msgs/Float32:整数、浮点数消息
  • std_msgs/Bool:布尔值消息

3.2 运动控制类型 (geometry_msgs)

机器人运动控制相关的消息类型:

  • geometry_msgs/Twist:速度消息,控制机器人运动的核心消息
    Vector3 linear # 线速度(x:前后, y:左右, z:上下) Vector3 angular # 角速度(x:翻滚, y:俯仰, z:偏航)
  • geometry_msgs/Pose:位姿消息,表示机器人的位置和姿态
    Point position # 位置(x,y,z) Quaternion orientation # 姿态(四元数)
  • geometry_msgs/PoseStamped:带时间戳的位姿消息,最常用的位姿消息
    Header header # 包含时间戳和坐标系 Pose pose

3.3 传感器类型 (sensor_msgs)

各种传感器数据的消息类型:

  • sensor_msgs/Imu:IMU 数据消息,包含加速度、角速度、姿态
    Header header Quaternion orientation # 姿态四元数 Vector3 angular_velocity # 角速度 Vector3 linear_acceleration # 线加速度
  • sensor_msgs/Image:图像消息,摄像头数据
  • sensor_msgs/LaserScan:激光雷达数据消息

四、总结:一张表记住五大核心组件

最后给大家整理了一张对比表,把今天讲的所有内容都浓缩进去了,建议截图保存。

ROS2 组件嵌入式类比核心功能通信模式典型使用场景
节点 (Node)FreeRTOS 任务执行具体功能传感器采集、电机控制、路径规划
话题 (Topic)消息队列 + 串口广播连续数据流传输异步、一对多发布传感器数据、速度指令
消息 (Message)C 语言结构体定义数据格式所有通信的数据载体
服务 (Service)函数调用 + 串口问答一次性请求响应同步、一对一拍照、启动设备、查询状态
参数 (Parameter)全局变量 + Flash 配置节点配置管理PID 参数、校准值、设备地址

写在最后

今天这篇文章,我用嵌入式工程师最熟悉的语言,把 ROS2 的五大核心组件全部翻译了一遍。相信你现在已经对 ROS2 有了一个清晰的整体认知,再也不会觉得 ROS2 的概念晦涩难懂了。

其实 ROS2 的本质就是一套标准化的通信框架,它把我们嵌入式开发中天天都在重复做的 "拆任务、定义协议、写通信" 这些工作,全部封装成了标准的组件。我们不用再去关心底层的通信细节,只需要专注于自己的业务逻辑就行。

这就是 ROS2 最大的价值:让机器人开发变得像搭积木一样简单


📢 下期连载预告

【ROS2 速成 - Day3】ROS2 命令行全套实操(开发天天用,必须练熟)

下一篇我会带大家手把手实操 ROS2 的所有常用命令,包括如何查看节点、话题、服务,如何发布消息、调用服务,如何设置参数。这些命令是你开发 ROS2 的时候天天都会用到的,必须练熟。

码字不易,欢迎点赞 + 收藏 + 关注,后续我会按【ROS2 速成 - DayX】的格式持续连载更新,分享 ROS2 嵌入式实战代码、硬件对接源码、项目工程模板,帮大家少踩坑,快速从嵌入式工程师转型 ROS2 开发。

有任何问题欢迎在评论区留言,我会一一回复。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/14 18:49:44

欧姆龙NX/NJ PLC数据采集,选FINS、Socket还是OPC UA?一张表帮你做对选择

欧姆龙NX/NJ PLC数据采集协议深度对比:从FINS到OPC UA的技术决策指南 在工业自动化项目中,数据采集作为连接物理设备与数字系统的桥梁,其协议选择直接影响着整个IIoT架构的稳定性与扩展性。欧姆龙NX/NJ系列PLC作为工业控制领域的核心设备&…

作者头像 李华
网站建设 2026/5/14 18:49:23

以凰为魂,以标为尺:《凰标》丈量华夏文艺万丈高度@凤凰标志

世间文艺之兴衰, 不在产量之多寡,不在流量之喧嚣, 而在标尺之正邪、维度之高低、气韵之深浅。一、弃己尺而用彼尺,百年之殇 百年以降,华夏文艺之所以屡遭矮化、屡陷迷茫、屡失风骨,根源在于—— 弃己尺而用…

作者头像 李华
网站建设 2026/5/14 18:46:52

长期项目中使用Taotoken观察到的API服务稳定性与支持体验

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期项目中使用Taotoken观察到的API服务稳定性与支持体验 在为期数月的实际开发项目中,我们选择将核心的智能对话功能通…

作者头像 李华
网站建设 2026/5/14 18:38:06

skynet笔记

文章目录API查阅一个独立的 Skynet 服务(Actor)消息头部的类型(ptype)字段。register_protocol的作用预定义常量自定义数字(类型)协程常见函数解析常见的字符串处理( Lua 标准字符串库的函数&am…

作者头像 李华