ROS2 Humble 笔记(四)ROS 的最小工作单元-- Node 节点

这篇博客是 B 站《古月·ROS2入门21讲》的第七个视频的图文记录,主要介绍了一个常规 ROS 节点的结构是怎样的、如何配置 python 节点的程序入口、基于 opencv 本地与摄像头画面的识别实现。原始视频链接如下:


1. hello world 节点体验

在正式解析节点之前先运行一下古月的官方代码仓库提供的节点,进入到上一篇博客的 dev_ws 工作空间下编译该空间:

bash 复制代码
$ cd dev_ws
$ colcon build

编译完成后 source 一下 install 目录下的环境变量:

bash 复制代码
$ source source install/local_setup.sh 

使用下面的命令运行节点,该节点会以 1 Hz 的频率在终端打印 Hello World 字段:

bash 复制代码
$ ros2 run learning_node node_helloworld

2. 节点结构 - [面向过程]

该文件位于 src/ros2_21_tutorials/learning_node/learning_node/node_hello_world.py 处:

你可以用 vim 或者 vscode 打开这个文件以查看该文件中的内容,这个节点的内容非常短:

python 复制代码
#!/usr/bin/env python3 
# -*- coding: utf-8 -*-

import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
import time

def main(args=None):                             # ROS2节点主入口main函数
    rclpy.init(args=args)                        # ROS2 Python接口初始化
    node = Node("node_helloworld")               # 创建ROS2节点对象并进行初始化
    
    while rclpy.ok():                            # ROS2系统是否正常运行
        node.get_logger().info("Hello World")    # ROS2日志输出
        time.sleep(0.5)                          # 休眠控制循环时间
    
    node.destroy_node()                          # 销毁节点对象    
    rclpy.shutdown()                             # 关闭ROS2 Python接口

核心代码由三部分构成:

  1. 初始化节点rclpy.initNode("")
  2. 功能实现:functions;
  3. 销毁节点destory_node()rclpy.shutdown()

使用下面命令启动节点:

bash 复制代码
$ ros2 run learning_node node_helloworld

3. 节点结构 - [面向对象]

该文件位于 dev_ws/src/ros2_21_tutorials/learning_node/learning_node/node_helloworld_class.py 处:

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
import time

class HelloWorldNode(Node):
    def __init__(self, name):
        super().__init__(name)                       # ROS2节点父类初始化
        while rclpy.ok():                            # ROS2系统是否正常运行
            self.get_logger().info("Hello World")    # ROS2日志输出
            time.sleep(0.5)                          # 休眠控制循环时间

def main(args=None):                                 # ROS2节点主入口main函数
    rclpy.init(args=args)                            # ROS2 Python接口初始化
    node = HelloWorldNode("node_helloworld_class")   # 创建ROS2节点对象并进行初始化
    node.destroy_node()                              # 销毁节点对象
    rclpy.shutdown()                                 # 关闭ROS2 Python接口

核心代码由三部分构成:

  1. 初始化节点rclpy.initNode("")
  2. 对象实例化:functions;
  3. 销毁节点destory_node()rclpy.shutdown()

使用下面的命令运行节点:

bash 复制代码
$ ros2 run learning_node node_helloworld_class 

4. python 程序入口点配置

只有当你的节点是以 python 形式实现的时候才需要配置程序入口点,C++ 实现的节点后面会介绍。

该文件位于 /dev_ws/src/ros2_21_tutorials/learning_node/setup.py 处,关注最下方 entry_points 字段:

python 复制代码
    entry_points={
        'console_scripts': [
         'node_helloworld       = learning_node.node_helloworld:main',
         'node_helloworld_class = learning_node.node_helloworld_class:main',
         'node_object            = learning_node.node_object:main',
         'node_object_webcam     = learning_node.node_object_webcam:main',
        ],
    },

其配置格式为,通常情况下会以脚本名作为可执行文件名,但这不是强制要求:

python 复制代码
可执行文件名 = 模块路径:main函数'
'node_name = learning_mix.node_name:main',

所有编译好的 python 节点会存储在 /home/orin/Desktop/dev_ws/install/learning_node/lib/learning_node 位置处:

【Note】:由于 python 本身是一个解释语言,因此即便是编译好的 lib 文件其本质上 仍是一个 python 文件,这和 C++ 生成一个二进制文件之间是有根本差异的。

你可以打开一个文件看看里面的内容,主要是写明了如何找到对应的 python 脚本位置。


5. 本地图像识别节点

作者在 src/ros2_21_tutorials/learning_node/learning_node/node_object.py 处提供了一个图像识别节点,你需要修改代码第 41 行附近的绝对路径,其原始文件就在当前目录下:

python 复制代码
def main(args=None):                                                              # ROS2节点主入口main函数
    rclpy.init(args=args)                                                         # ROS2 Python接口初始化
    node = Node("node_object")                                                     # 创建ROS2节点对象并进行初始化
    node.get_logger().info("ROS2节点示例:检测图片中的苹果")

    # image = cv2.imread('/home/hcx/dev_ws/src/ros2_21_tutorials/learning_node/learning_node/apple.jpg')  # 读取图像
    image = cv2.imread('/home/orin/Desktop/dev_ws/src/ros2_21_tutorials/learning_node/learning_node/apple.jpg')
    
    object_detect(image)                                                            # 苹果检测
    rclpy.spin(node)                                                               # 循环等待ROS2退出
    node.destroy_node()                                                            # 销毁节点对象
    rclpy.shutdown()                                                               # 关闭ROS2 Python接口

在你的环境中安装 python3-opencv

bash 复制代码
$ sudo apt-get install python3-opencv

运行该节点:

bash 复制代码
$ ros2 run learning_node node_object

如果你在运行后出现以下报错:

bash 复制代码
cv2.error: OpenCV(4.5.4) ./modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

可能是因为修改了 python 文件后没有重新编译的原因(这一点和 ROS1 存在显著区别),重新编译一下工作空间后再运行即可:

bash 复制代码
$ colcon build
$ ros2 run learning_node node_object

6. 摄像头图像识别节点

作者在该功能包下还提供了一个使用摄像头进行图像识别的节点,但由于我的设备上没有摄像头硬件,因此在这里就不进行演示了,有条件的读者可以直接运行下面的命令:

bash 复制代码
$ ros2 run learning_node node_object_webcam 
相关推荐
八月瓜科技6 小时前
用AI来省电?iOS26.5正式版全球推送:信号弱网双提升,AI省电模式上新
数据库·人工智能·科技·深度学习·机器人
小陈phd6 小时前
多模态大模型学习笔记(四十)——从“看字”到“懂结构”:版面分析与表格解析技术全解
笔记·学习
xuhaoyu_cpp_java7 小时前
SpringMVC学习(二)
java·经验分享·笔记·学习·spring
噜噜噜阿鲁~8 小时前
python学习笔记 | 9.2、模块-安装第三方模块
笔记·python·学习
我胖虎不答应!!9 小时前
Three.js开发思想笔记
javascript·笔记·three.js
2601_957964879 小时前
618.4V锂电池完整设计方案要求【浩博电池】
机器人
程序leo源9 小时前
C语言知识总结
c语言·开发语言·c++·经验分享·笔记·青少年编程·c#
羊群智妍10 小时前
2026年GEO优化实战:AI搜索优化监测工具全解析
笔记
中屹指纹浏览器10 小时前
2026浏览器插件指纹溯源机制与插件环境安全优化实战指南
经验分享·笔记
想学会c++10 小时前
单例模式笔记总结
c++·笔记·单例模式