ROS2节点:机器人的工作细胞

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 高内聚低耦合

  • 高内聚:节点内部功能紧密相关
  • 低耦合:节点之间依赖最小化
相关推荐
冰心少年2 小时前
ROS2话题:节点间传递数据的桥梁
后端
星辰徐哥2 小时前
异步定时任务系统的设计与Rust实战集成
开发语言·后端·rust
海兰2 小时前
【springboot】gradle快速镜像配置
spring boot·笔记·后端
武超杰2 小时前
SpringBoot 整合 Spring Security 实现权限控制
spring boot·后端·spring
XMYX-03 小时前
06 - Go 的切片、字典与遍历:从原理到实战
后端·golang
架构师专栏3 小时前
比 MQ 更轻的异步方案:Spring 内置的这个隐藏功能,很多人还不知道
后端
林木883 小时前
Druid Kafka 数据源消费到 Segment 生成全链路深度分析
后端
摇曳的精灵3 小时前
Spring boot注解实现信息脱敏
java·spring boot·后端·注解脱敏·信息脱敏
程序猿大帅3 小时前
记一次线上翻车:加了Redisson分布式锁,数据还是被并发打穿了
后端