1.什么是ROS2节点?
1.1 节点的定义
在ROS2中,节点(Node)是执行计算任务的基本单元。就像人体中的细胞一样:
- 每个节点都有明确的功能职责
- 节点之间通过"血管"(通信机制)传递信息
- 多个节点协同工作,构成完整的机器人系统
1.2 节点的本质
从编程角度看,节点是一个可执行的进程:
- 每个节点都是一个可以独立运行的可执行文件:例如执行某个 Python 程序,或者执行 C++编译生成的结果,都算运行了一个节点。
- 每个节点可使用不同的编程语言:既然每个节点都是独立的执行文件,那得到这个执行文件的编程语言就可以是不同的,例如C++ 、Python等。
- 每个节点都需要唯一的名称:在 ROS 2系统中,所有节点是通过名称进行管理的,当大家想要找到某个节点或者了解某个节点的状态时,可以通过节点的名称查询。
2.节点编程方法
2.1 创建ROS2包
css
# 在ROS2工作空间的src目录下执行
ros2 pkg create --build-type ament_python hello_world_pkg --license Apache-2.0
2.2 编写节点代码
在 hello_world_pkg/hello_world_pkg/ 目录下创建 hello_world_node.py:
python
import rclpy #ROS2的Python接口库
from rclpy.node import Node
import time
class HelloWorldNode(Node):
def __init__(self):
super().__init__('hello_world_node')
self.get_logger().info('Hello World节点已启动')
# 创建定时器,每1秒调用一次定时器回调函数
self.timer = self.create_timer(1.0, self.timer_callback)
def timer_callback(self):
# 输出Hello World
self.get_logger().info('Hello World')
def main(args=None):
# 初始化ROS2客户端库
rclpy.init(args=args)
# 创建节点实例
node = HelloWorldNode()
try:
# 循环运行节点,直到被中断
rclpy.spin(node)
except KeyboardInterrupt:
# 处理Ctrl+C中断
node.get_logger().info('节点被用户中断')
finally:
# 清理资源
node.destroy_node()
rclpy.shutdown()
上面的代码没有运行main函数,那么节点要如何运行呢? 别急,我们在后面的代码中会进行配置
2.3 更新 setup.py
编辑 hello_world_pkg/setup.py,添加入口点:
ini
from setuptools import find_packages, setup
package_name = 'hello_world_pkg'
setup(
...
entry_points={
'console_scripts': [
'hello_world_node = hello_world_pkg.hello_world_node:main'
],
},
)
注意:对于Python 功能包中的代码,每个节点都需要进行类似的入口配置,如果配置错误或者忘记配置,则可能导致运行时找不到对应的可执行文件。
2.4 构建和运行
bash
#回到工作空间根目录
#构建包
colcon build --packages-select hello_world_pkg
# 设置环境变量
source install/setup.bash
# 运行节点
ros2 run hello_world_pkg hello_world_node
注意:source install/setup.bash设置的是临时的环境变量,每次打开新的终端都需要运行source install/setup.bash。也可以写入.bashrc文件,设置成永久的环境变量,这样每次打开新的终端不需要运行source install/setup.bash。
bash
echo "source [工作空间根目录]/install/setup.bash" >> ~/.bashrc
#learn_ws工作空间
echo "source ~/learn_ws/install/setup.bash" >> ~/.bashrc
修改后的.bashrc文件内容

2.5 输出示例
运行后会看到类似下面的输出,每秒输出一次"Hello World":

3.节点的命令行操作
3.1 节点的相关命令
ini
ros2 node list #查看节点列表
ros2 node info [node_name] #查看节点信息
3.2 输出示例
输入:
ros2 node list
输出
bash
/hello_world_node
注意:我们在代码中提供了节点的基础名称 hello_world_node。ROS2 核心接收到这个相对名称后,自动为其补全根命名空间,形成绝对名称 /hello_world_node。所以我们看到的是 /hello_world_node。
节点的命名空间:用于将节点逻辑分组,避免节点名称冲突,并方便参数和主题的引用。你可以将命名空间理解为类似文件系统的目录路径。
- 节点在全局 下的完整名称 =
命名空间+/+节点名称 - 如果节点没有指定命名空间,则默认在根命名空间
/下 - 命名空间可以嵌套 ,例如
/sensor/lidar
4.节点设计原则
4.1 单一职责原则
每个节点只做一件事,并把它做好
diff
❌ 错误示例:
一个节点同时负责:激光雷达处理 + 路径规划 + 电机控制
✅ 正确示例:
- lidar_processor_node:只处理激光雷达数据
- path_planner_node:只做路径规划
- motor_controller_node:只控制电机
4.2 高内聚低耦合
- 高内聚:节点内部功能紧密相关
- 低耦合:节点之间依赖最小化