ROS2从零入门:彻底搞懂节点+编写第一个自定义节点
在上一篇博客中我们掌握了 ROS2 环境配置、命令行启动程序、CMake 编译工具的使用解决了如何运行ROS2程序的问题。而今天我们深入底层核心讲解 ROS2 最基础、最重要的核心单元——节点Node。所有 ROS2 机器人功能无论是建图、导航、视觉识别、电机控制本质上都是由一个个独立的节点协同完成。可以说学会写节点才算真正入门 ROS2 开发。本文将从零讲解节点核心概念搭配可直接复制运行的 C 源码手把手教你完成「编写节点→配置编译规则→编译程序→运行调试」完整闭环适配 Humble/Iron/Jazzy 全版本。一、什么是 ROS2 节点通俗理解1. 节点的定义在 ROS2 中节点Node是执行单一特定功能的最小可执行单元是编译后可以独立运行的程序。我们可以把机器人系统类比成一个团队每个节点就是一个独立的工作人员雷达节点专门负责采集环境雷达数据相机节点专门负责采集图像画面导航节点专门负责路径规划、点位导航电机控制节点专门负责控制机器人运动每个节点各司其职、独立运行通过话题、服务等方式互相通信最终实现机器人的完整功能。2. 节点的核心优势模块化解耦单个节点故障不会导致整个系统崩溃稳定性更强可复用性高写好的节点可直接复用在不同机器人项目中调试简单可单独启动、单独调试某个功能模块3. 节点、功能包、可执行文件的关系很多新手容易混淆三者关系这里做清晰梳理功能包Package存放源码、配置文件的文件夹是项目管理单元节点源码我们编写的 .cpp 代码是节点的原始程序节点可执行文件源码经过 CMake 编译后生成的可运行程序也就是我们用ros2 run启动的程序二、自定义节点开发前置准备默认你已经配置好 ROS2 环境、创建好了工作空间ros2_ws我们先创建一个全新的自定义功能包用于存放我们的第一个节点。1. 创建自定义功能包进入工作空间 src 目录创建依赖 rclcppROS2 C 核心库的功能包cd ~/ros2_ws/src ros2 pkg create my_first_node --build-dependencies rclcpp命令释义创建名为my_first_node的功能包默认依赖 C 节点核心库 rclcpp。2. 创建源码文件夹进入功能包新建 src 文件夹规范存放源码文件cd ~/ros2_ws/src/my_first_node mkdir src三、手把手编写第一个 ROS2 C 节点我们编写一个最简单的日志输出节点实现节点启动后循环打印日志验证节点正常运行。在src目录下新建文件hello_node.cpp写入以下完整源码。1. 完整节点源码可直接复制// 引入ROS2 C核心头文件 #include rclcpp/rclcpp.hpp // 主函数程序入口 int main(int argc, char ** argv) { // 1. 初始化ROS2节点环境 rclcpp::init(argc, argv); // 2. 创建一个节点命名为 hello_world_node auto node std::make_sharedrclcpp::Node(hello_world_node); // 3. 循环输出日志每秒打印一次 rclcpp::Rate loop_rate(1.0); // 设置频率1Hz while (rclcpp::ok()) // 节点正常运行时循环 { // 打印INFO级别日志 RCLCPP_INFO(node-get_logger(), 成功运行第一个ROS2节点Hello ROS2!); loop_rate.sleep(); // 休眠控制循环频率 } // 4. 关闭节点环境 rclcpp::shutdown(); return 0; }2. 代码逐行核心解析新手必看#include rclcpp/rclcpp.hpp引入 ROS2 C 节点核心库所有 C 节点必须包含该头文件rclcpp::init(argc, argv)初始化 ROS2 通信环境是节点运行的第一步std::make_sharedrclcpp::Node(hello_world_node)创建节点实例hello_world_node 是节点名称全局唯一rclcpp::Rate loop_rate(1.0)设置循环运行频率1.0代表1秒执行一次rclcpp::ok()判断节点是否处于正常运行状态按下 CtrlC 后终止循环RCLCPP_INFOROS2 标准日志打印函数替代普通 printf可输出日志级别、时间戳rclcpp::shutdown()关闭节点释放资源程序结束四、配置 CMakeLists.txt 编译规则关键步骤写完源码后必须配置编译规则告诉 CMake 如何编译源码、生成可执行文件、安装运行文件。打开功能包根目录的CMakeLists.txt替换为以下完整配置衔接上一篇博客的CMake知识点。cmake_minimum_required(VERSION 3.8) project(my_first_node) # 查找依赖包 find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) # 编译可执行节点源码文件 生成的节点名 add_executable(hello_node src/hello_node.cpp) # 绑定节点依赖 ament_target_dependencies(hello_node rclcpp) # 安装节点让ros2 run可以识别 install(TARGETS hello_node DESTINATION lib/${PROJECT_NAME} ) ament_package()核心重点add_executable定义了最终的可执行文件名hello_node后续启动节点需要使用该名称。五、编译运行节点完整流程1. 编译功能包返回工作空间根目录执行编译命令cd ~/ros2_ws colcon build --packages-select my_first_node2. 加载环境变量编译完成后必须加载环境否则无法识别新节点source install/setup.bash3. 启动自定义节点使用上一篇博客的ros2 run命令启动单个节点ros2 run my_first_node hello_node4. 运行效果终端会每秒循环打印日志代表节点运行成功[INFO] 成功运行第一个ROS2节点Hello ROS2!按下CtrlC即可关闭节点。六、验证节点状态调试实操保持节点运行新开终端加载环境通过调试命令验证节点状态# 查看所有运行节点 ros2 node list # 查看节点详细信息 ros2 node info /hello_world_node可以看到我们创建的hello_world_node节点证明节点注册、运行完全正常。七、新手开发常见报错避坑编译成功但无法启动节点CMakeLists 未配置 install 安装规则节点未部署到运行目录重新配置并清理缓存编译提示节点不存在编译后未执行 source 环境变量或可执行文件名输入错误代码报错rclcpp未定义package.xml 和 CMakeLists 中未添加 rclcpp 依赖节点启动瞬间闪退代码缺少循环逻辑节点执行完毕后自动退出需添加 while 循环常驻运行八、总结与进阶方向通过本文我们彻底理解了 ROS2 节点的核心概念同时完成了从0编写、配置、编译到运行的完整节点开发流程。这是所有 ROS2 进阶开发的基础后续的话题通信、服务通信、参数配置、传感器开发都是在节点的基础上延伸拓展。简单复盘核心要点节点是ROS2最小可执行功能单元模块化分工运行C节点开发核心四步建包→写源码→配CMake→编译运行必须初始化、注册节点、循环常驻、最后关闭节点下一篇我们可以基于该节点讲解ROS2话题通信实现节点之间的数据收发真正实现多节点协同工作。