核心概念:节点、话题、服务、动作、参数的定义与作用
在深入 ROS2 的代码实现之前,必须先建立一套清晰的心智模型。ROS2 的通信机制并非单一协议,而是由五种核心概念共同构成的协作体系:节点是执行单元,话题与服务是同步/异步的两种数据通路,动作是面向长时任务的“服务升级版”,参数则是运行时的配置接口。理解它们各自的定位与边界,是后续编写可靠机器人程序的前提。
3.1 节点:功能的最小执行单元
节点(Node)是 ROS2 中一个可执行文件内实现特定功能的进程模块。一个机器人系统通常由多个节点组成,例如:/camera_node 负责采集图像,/lidar_node 处理激光扫描,/nav_node 负责路径规划。每个节点在计算图中拥有唯一的名称,并通过 DDS(数据分发服务)与外界通信。
节点的核心价值在于故障隔离与复用性。如果导航节点崩溃,摄像头节点不会受影响,系统仍可降级运行。在代码层面,节点通过 rclcpp::Node 类创建,其构造函数中可声明话题发布者、订阅者、服务端等通信对象。
// 创建节点的典型 C++ 代码结构
#include "rclcpp/rclcpp.hpp"
class MyNode : public rclcpp::Node {
public:
MyNode() : Node("my_node_name") {
// 在此处创建发布者、订阅者、服务等
}
};
int main(int argc, char** argv) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MyNode>());
rclcpp::shutdown();
return 0;
}
component 机制),但通常建议一个节点对应一个独立功能模块,便于调试与资源管理。
3.2 话题:持续单向的数据流
话题(Topic)是 ROS2 中最常用的通信方式,采用发布/订阅模式。发布者(Publisher)将消息广播到指定名称的话题上,订阅者(Subscriber)接收该话题的所有消息。话题通信是异步、单向、多对多的:一个话题可有多个发布者和多个订阅者,双方无需等待对方响应。
话题适用于高频、周期性、持续更新的数据,如传感器数据、状态估计、控制指令。其底层基于 DDS 的 QoS(服务质量)策略,可控制消息的可靠性、历史深度和时效性。例如,激光雷达点云适合 RELIABLE 传输,而 IMU 姿态数据可用 BEST_EFFORT 降低延迟。
.msg 文件中定义,编译后生成对应语言的类。查看当前所有话题可用命令:ros2 topic list,查看话题实时数据流:ros2 topic echo /topic_name。
3.3 服务:同步的请求-应答
服务(Service)用于一次性、短时、需要立即返回结果的交互。客户端(Client)发送请求,服务端(Server)处理并返回响应,整个过程是同步阻塞的。服务由 .srv 文件定义,包含请求(Request)和响应(Response)两部分。
典型场景包括:查询机器人状态(如“当前电量是多少?”)、触发一次性动作(如“开启机械臂夹爪”)、设置参数(如“切换到自主导航模式”)。服务不适合传输大规模连续数据,因为每次调用都有网络往返开销。
# 服务接口定义示例:SetLED.srv
# 请求部分
bool enable # 是否点亮
int32 brightness # 亮度值 0-255
# 响应部分
bool success # 是否成功
string message # 结果描述
3.4 动作:长时任务的“服务+反馈”
动作(Action)是 ROS2 为长时间执行、需要中途反馈、可被取消的任务设计的通信机制。它由三部分组成:目标(Goal)、反馈(Feedback)和结果(Result)。动作客户端发送目标后,服务端持续执行,并周期性发送反馈;任务完成后返回最终结果。
动作的典型应用是导航到目标点、机械臂抓取、自主充电等。与普通服务相比,动作支持任务执行过程中的实时监控与取消操作。动作接口由 .action 文件定义,内部自动生成三个话题:/goal、/feedback、/result,以及一个取消服务。
| 通信方式 | 方向 | 同步性 | 适用场景 | 典型示例 |
|---|---|---|---|---|
| 话题 | 单向流 | 异步 | 高频持续数据 | /camera/image_raw |
| 服务 | 请求-应答 | 同步 | 短时查询/触发 | /set_led |
| 动作 | 目标-反馈-结果 | 异步+反馈 | 长时可取消任务 | /navigate_to_pose |
| 参数 | 节点配置 | 同步 | 运行时参数调整 | /nav_node/max_speed |
3.5 参数:节点的运行时配置
参数(Parameter)是附着在节点上的键值对,用于配置节点行为而不需要重新编译代码。每个节点维护自己的参数列表,可通过命令行、代码或 YAML 文件动态设置。参数类型支持整数、浮点、布尔、字符串、数组等。
参数与话题/服务的本质区别在于:参数不属于通信通道,而是节点内部的配置状态。但 ROS2 提供了参数服务(/parameter_events),允许其他节点远程读取或修改某节点的参数,这本质上是一种特殊服务调用。
/nav_node/max_speed,而不是创建一个名为 /max_speed 的话题。话题用于传输状态数据,参数用于配置项。若某个值需要被多个节点共享且频繁变化,才考虑用话题。
3.6 综合案例:导航任务中的概念协作
假设机器人需要从当前位置导航到坐标 (5.0, 3.0),完整流程展示了各概念的配合:
- 参数读取:导航节点启动时从参数服务器读取
max_speed、goal_tolerance等配置。 - 话题订阅:持续接收
/scan(激光雷达)和/odom(里程计)话题数据,构建环境地图并定位。 - 服务调用:调用
/map_server的/load_map服务加载静态地图。 - 动作发送:向
/navigate_to_pose动作服务器发送目标坐标,开始导航。 - 反馈循环:动作服务器在导航过程中通过反馈通道发送当前进度(如“剩余距离 2.3m”),导航节点可据此更新状态显示。
- 话题发布:导航节点将计算出的速度指令发布到
/cmd_vel话题,底盘驱动节点订阅后执行。
这个案例清晰展示了:话题负责“感知-决策-执行”的持续数据流,服务处理离散的查询/配置请求,动作管理需要监控的长时任务,参数提供灵活的运行时配置。理解这五种概念的分工,是设计复杂机器人软件架构的基础。