ROS2 基础 (一) - 第一个节点和包
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的当前目录进行操作
在ubuntu的vscode中安装pylance插件,鼠标悬停在函数、类等处可便捷查看文档说明,使用滚轮可滑动查看完整文档
5. 环境验证
-
新建两个终端(A、B)
终端 A 运行一个持续发布消息的 talker:
ros2 run demo_nodes_cpp talker终端 B 运行一个持续订阅消息的 listener:
ros2 run demo_nodes_py listener若终端 B listener 持续收到来自终端A talker 的消息,说明 ROS2 安装成功。
-
新建三个终端(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,刷新一下,可看到之前打开的节点间的关系
6. ROS2架构学习
- 操作系统层(Operating System Layer):驱动计算机硬件、网络通信
-
DDS实现层(DDS Implementation Layer):
DDS( Data Distribution Service ,数据分发服务),是由对象管理组织制定的分布式实时通信中间件技术规范,采用发布/订阅体系架构。ROS2采用DDS进行节点间通信
数据发送者不必关心接收者的目的地址和数量,数据接收者不必关心发送地址和数量,仅需根据主题进行相应消息的收发。
在之前的乌龟实验中,teleop_turtle节点对turtle1/cmd_vel这个主题发布了消息,由于turtlesim订阅了该主题,消息被发送至turtlesim,由此完成控制命令的传递
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的节点
3、创建第一个包
- 创建一个名字叫做 my_package 的功能包
# 创建一个名为my_package的功能包,使用ament编译,依赖rclpy库
ros2 pkg create my_package --build-type ament_python --dependencies rclpy
当前目录下自动生成了一个名为my_package的功能包文件夹
- 在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
- 然后声明该节点:在my_package/setup.py文件中修改entry_points入口参数:
entry_points={
'console_scripts': [
"node2 = my_package.second_node:main"
],
},
其中node2即为executable_name,my_package.second_node:main为该节点的入口函数路径(即my_package/my_package/second_node.py文件中的main函数)
- 在工作空间(第一层my_package/)下编译功能包
colcon build
colcon是ROS2推荐的构建工具,通过调用CMake或Python的setuptools等工具进行构建,支持多包构建和依赖管理
- 编译完成后,source安装目录下的setup.bash文件以加载环境
source install/setup.bash
- 运行程序
ros2 run my_package node2
可看到终端输出了日志信息
- 面向对象编程方式创建节点
节点的概念很适合面向对象编程,我们可以将节点封装成一个类,继承自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"
],
},
按上述步骤编译运行