← 返回

ROS2 基础 (一) - 第一个节点和包

ROS2 • 2026年5月21日

1. 说明

ROS(Robot Operating System)是一个开源的机器人软件框架,提供通信机制、构建工具和大量功能包,便于快速开发机器人应用。

本文以 ROS 2 Kilted Kaiju 为例,演示在 WSL2 下的 Ubuntu 24.04(Noble)中的安装与验证流程。

  • ROS 2 官方安装文档:https://docs.ros.org/en/kilted/Installation.html
  • WSL 官方安装文档:https://learn.microsoft.com/zh-cn/windows/wsl/install

2. 环境建议

  • 操作系统:Ubuntu 24.04(Noble)
  • 安装场景:WSL / 虚拟机(VMWare/VirtualBox) / 物理机
  • 网络要求:可访问 GitHub 与 Ubuntu 软件源

3. 安装ROS

在Windows命令行中安装WSL下的Ubuntu 24.04

# 1) 安装Ubuntu-24.04
wsl --install Ubuntu-24.04
# 2) 设置wsl默认发行版
wsl --set-default Ubuntu-24.04
# 3)进入Ubuntu终端
wsl

在 Ubuntu 终端中依次执行以下命令(来自官方安装文档):

# 1) 启用 Ubuntu Universe 仓库

sudo apt install -y software-properties-common
sudo add-apt-repository universe

# 2) 配置 ROS 2 APT 软件源

sudo apt update && sudo apt install -y curl
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F'"' '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"
sudo dpkg -i /tmp/ros2-apt-source.deb

# 3) 安装开发工具

sudo apt update && sudo apt install -y ros-dev-tools

# 4) 安装 ROS 2 桌面版

sudo apt update
sudo apt upgrade -y
sudo apt install -y ros-kilted-desktop

# 5) 设置 ROS 环境

source /opt/ros/kilted/setup.bash
# 如果你使用的不是 bash,请替换为对应脚本:
# setup.bash
# setup.sh
# setup.zsh

# 6) 设置自启 ROS 环境
echo "source /opt/ros/kilted/setup.bash" >> ~/.bashrc

4. 代码编辑器配置

本文以VSCode为编辑器,python为开发语言

在VSCode中安装WSL插件,在WSL终端中输入命令code .即可在vscode中对wsl的当前目录进行操作

WSL

在ubuntu的vscode中安装pylance插件,鼠标悬停在函数、类等处可便捷查看文档说明,使用滚轮可滑动查看完整文档

pylance

5. 环境验证

  1. 新建两个终端(A、B)

    终端 A 运行一个持续发布消息的 talker:

    ros2 run demo_nodes_cpp talker

    终端 B 运行一个持续订阅消息的 listener:

    ros2 run demo_nodes_py listener

    若终端 B listener 持续收到来自终端A talker 的消息,说明 ROS2 安装成功。

    验证安装完毕
  2. 新建三个终端(A、B、C)

    终端 A 启动海龟模拟器

    ros2 run turtlesim turtlesim_node
    海龟模拟器

    终端 B 启动海龟远程遥控

    ros2 run turtlesim turtle_teleop_key

    此时在终端B中可使用上下左右方向键控制海龟的转向和移动

    海龟遥控器

    终端 C 启动 RQt (ROS Qt-based GUI Framework)

    rqt

    选中Plugins->Introspection->Node Graph,刷新一下,可看到之前打开的节点间的关系

    rqt

6. ROS2架构学习

Architecture
  • 操作系统层(Operating System Layer):驱动计算机硬件、网络通信
  • DDS实现层(DDS Implementation Layer):

    DDS( Data Distribution Service ,数据分发服务),是由对象管理组织制定的分布式实时通信中间件技术规范,采用发布/订阅体系架构。ROS2采用DDS进行节点间通信

    数据发送者不必关心接收者的目的地址和数量,数据接收者不必关心发送地址和数量,仅需根据主题进行相应消息的收发。

    在之前的乌龟实验中,teleop_turtle节点对turtle1/cmd_vel这个主题发布了消息,由于turtlesim订阅了该主题,消息被发送至turtlesim,由此完成控制命令的传递

    DDS

    DDS实现层对不同常见的DDS接口进行再次的封装

  • 抽象DDS层(Abstract DDS Layer):对DDS实现层进一步封装,省去大量的配置工作
  • ROS2客户端层(ROS2 Client Layer):为上层应用提供API接口,即RCL(ROS Client Library,ROS客户端库),有python,c++等不同实现
  • 应用层(Application Layer):编写开发的机器人应用

一、第一个节点和功能包

1、节点学习

节点可视作一个单独的模块化功能(比如一个节点负责控制车轮转动、一个节点负责定位等等)

节点和节点间有四种通信方式:

  • 话题-topics
  • 服务-services
  • 动作-Action
  • 参数-parameters

启动一个节点

# 启动包package_name中的可执行文件executable_name
ros2 run <package_name> <executable_name>

ros2 run turtlesim turtlesim_node

其中package在某工作空间(文件夹)内,一个工作空间下可以有多个功能包,一个功能包可以有多个节点存在

查看节点列表

ros2 node list

查看节点信息

# 查看节点node_name的信息
ros2 node info <node_name>

2、创建第一个节点

新建一个文件夹和python文件(如ROS2/first_node.py),输入以下代码:

# !/usr/bin/env python3
# 导入rclpy库
import rclpy
from rclpy.node import Node
# 调用初始化函数
rclpy.init()
# 创建节点“first_node”并循环运行
rclpy.spin(Node("first_node"))

新建两个终端(A、B),终端A运行first_node.py

python3 first_node.py

终端B运行命令查看当前ROS2系统中的节点

ros2 node list

可看到成功创建了一个名为first_node的节点

ROS2节点列表

3、创建第一个包

  1. 创建一个名字叫做 my_package 的功能包
# 创建一个名为my_package的功能包,使用ament编译,依赖rclpy库
ros2 pkg create my_package --build-type ament_python --dependencies rclpy
创建功能包

当前目录下自动生成了一个名为my_package的功能包文件夹

  1. 在my_package/my_package/目录下创建一个python文件(如second_node.py),并输入以下代码:
import rclpy
from rclpy.node import Node
def main(args=None):
    """
    ros2运行该节点的入口函数
    编写ROS2节点的一般步骤
    1. 导入库文件
    2. 初始化客户端库
    3. 新建节点对象
    4. spin循环节点
    5. 关闭客户端库
    """
    rclpy.init(args=args) # 初始化rclpy
    node = Node("node_02") # 新建一个节点
    node.get_logger().info("大家好,我是node_02.") # 输出日志信息
    rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
    rclpy.shutdown() # 关闭rclpy
  1. 然后声明该节点:在my_package/setup.py文件中修改entry_points入口参数:
entry_points={
        'console_scripts': [
            "node2 = my_package.second_node:main"
        ],
    },

其中node2即为executable_namemy_package.second_node:main为该节点的入口函数路径(即my_package/my_package/second_node.py文件中的main函数)

  1. 在工作空间(第一层my_package/)下编译功能包
colcon build

colcon是ROS2推荐的构建工具,通过调用CMake或Python的setuptools等工具进行构建,支持多包构建和依赖管理

编译功能包
  1. 编译完成后,source安装目录下的setup.bash文件以加载环境
source install/setup.bash
  1. 运行程序
ros2 run my_package node2

可看到终端输出了日志信息

运行节点
  1. 面向对象编程方式创建节点

节点的概念很适合面向对象编程,我们可以将节点封装成一个类,继承自Node类,并在类中定义节点的功能和行为

# my_package/my_package/third_node.py
import rclpy
from rclpy.node import Node

class Node03(Node):
    """
    创建一个名为Node03的节点类,继承自Node类
    初始化时输出一句日志信息
    """
    def __init__(self,name):
        super().__init__(name) # 初始化父类Node
        self.get_logger().info(f"大家好,我是{name}.") # 输出日志信息

def main(args=None):
    rclpy.init(args=args) # 初始化rclpy
    node = Node03("node_03") # 新建一个节点对象,传入节点名称参数
    rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
    rclpy.shutdown() # 关闭rclpy,正常无法到达该语句

声明该节点

entry_points={
        'console_scripts': [
            "node2 = my_package.second_node:main",
            "node3 = my_package.third_node:main"
        ],
    },

按上述步骤编译运行

OOP