拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ROS2系列教程:Humble环境搭建与Hello World

本文是 ROS2 系列教程的第 1 篇本文是 ROS2 系列教程的第 1 篇Humble 环境搭建与 Hello World。本系列参照「动手学 ROS2」Humble LTS 的知识体系采用 Crclcpp与 Pythonrclpy双语言并讲的方式从零开始带你掌握 ROS2 的核心概念与实战技巧。每一篇都会给出可运行的完整示例建议你在自己的机器上亲自动手实践。一、ROS2 是什么ROSRobot Operating System机器人操作系统并不是一个真正的操作系统而是一套面向机器人与自动化系统的分布式中间件框架。它建立在 Linux 等宿主操作系统之上为机器人软件提供统一的通信、调度、工具链与生态。ROS2 是 ROS1 的全新重写版本解决了 ROS1 在实时性、多机通信、安全性、跨平台以及长期支持方面的诸多痛点。本节先建立整体认知不必着急记细节后续章节会逐个展开。1.1 ROS1 与 ROS2 的核心区别ROS1 面向学术与原型验证虽成熟但存在先天限制ROS2 面向工业级与生产部署做了架构性升级。理解它们的差别有助于我们理解 ROS2 设计中那些看似「多此一举」的概念。维度ROS1ROS2通信中间件自研 TCPROS / UDPROSDDS数据分发服务实时性较弱无 QoS 保障强支持 QoS 服务质量策略多机/分布式依赖一台 ROS Master无需中心节点DDS 自动发现跨平台主要 LinuxLinux/Windows/macOS安全性无加密与身份认证支持 SROS2 加密与认证Python 消息分发需要 rospy 全局状态纯 Python rclpy长期支持无 LTS 概念有 LTS 版如 Humble最大的架构差异在于去中心化。ROS1 必须有一个roscoreROS Master来维护节点注册与话题匹配Master 一旦挂掉整个系统瘫痪ROS2 基于 DDS 的 P2P 发现机制节点之间直接协商通信无需单点故障中心。这也是 ROS2 适合多机、长时间部署机器人的根本原因。1.2 DDS 与 QoSDDSData Distribution Service是一个由 OMG 组织维护的发布/订阅式实时通信标准。DDS 本身蕴含了节点发现、可靠传输、权限控制、QoS 策略等能力ROS2 选择 DDS 作为通信底座使自己能直接复用这些工业级能力。QoSQuality of Service服务质量是 ROS2 通信的核心概念它决定消息传输的可靠性与实时性。ROS2 常用的 QoS 策略包括Reliability可靠性RELIABLE尽力可靠送达可能重传BEST_EFFORT尽力而为不重传适合高带宽传感器。Durability持久性TRANSIENT_LOCAL让晚加入的订阅者也能收到最近的「最后一条」消息常用于参数、静态 TFVOLATILE只收发布之后的消息。History历史KEEP_LAST(N)只保留最近 N 条KEEP_ALL保留全部。Deadline / Lifespan / Liveliness用于超时、有效期与活性检测。同一话题上的发布者与订阅者 QoS必须兼容才能通信。例如发布者用RELIABLE订阅者用BEST_EFFORT可以兼容可靠侧向下兼容但反过来则不行。第 9 篇会专门深入 QoS这里先记住QoS 是 ROS2 中「看似啰嗦、实则关键」的设计。1.3 版本与 LTSROS2 每年发布一个版本奇数为 LTS偶数为半年版。当前主流长期支持版是Humble HawksbillHumbleH 系列支持到约 2027 年也是 fishros「动手学 ROS2」教程采用的版本。其余常见版本如 Foxy、Galactic、Iron、Jazzy、Kilted 等。我们统一使用Ubuntu 22.04 Humble这套最经典的组合社区资料最丰富、踩坑最少。二、环境搭建搭建 ROS2 Humble 环境的推荐方式是「在 Ubuntu 22.04 上安装」。如果你没有 Ubuntu 物理机可考虑以下方案按简单到复杂排列WSL2、虚拟机VirtualBox / VMware、Docker。本教程以Windows 上的 WSL2 Ubuntu 22.04为例因为它既能利用 Windows 硬件又让开发体验接近原生 Linux。2.1 WSL2 安装步骤在 Windows 上打开「管理员 PowerShell」依次执行# 启用 WSL2 并安装 Ubuntu 22.04wsl--install-dUbuntu-22.04重启计算机后首次启动 Ubuntu-22.04 会让你设置 Linux 用户名与密码。安装完成后可更新系统软件包sudoaptupdatesudoaptupgrade-y如果你的 Windows 版本较老wsl --install可能不支持需要手动启用 WSL 功能与虚拟机平台控制面板 → 启用或关闭 Windows 功能 → 勾选「适用于 Linux 的 Windows 子系统」与「虚拟机平台」。2.2 设置 locale 与软件源ROS2 对 locale 有要求必须先配置为 UTF-8 编码否则中文与特殊字符会出问题sudoaptinstall-ylocalessudolocale-gen en_US en_US.UTF-8sudoupdate-localeLC_ALLen_US.UTF-8LANGen_US.UTF-8exportLANGen_US.UTF-8然后设置 UTF-8 软源如需并安装基础依赖sudoaptinstall-ysoftware-properties-commoncurlgnupg2 lsb-release2.3 添加 ROS2 apt 源以 Humble 为例添加官方软件源sudocurl-sSLhttps://raw.githubusercontent.com/ros/rosdistro/master/ros.key-o/usr/share/keyrings/ros-archive-keyring.gpgechodeb [arch$(dpkg --print-architecture)signed-by/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu$(source/etc/os-releaseecho$UBUNTU_CODENAME)main|sudotee/etc/apt/sources.list.d/ros2.list/dev/null国内网络较慢时可以改用清华镜像源加速sudosh-cecho deb [arch$(dpkg --print-architecture)] https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros2.list更新索引后即可安装 ROS2 核心包。选择「ros-base」即可满足大部分教程需求如需更多工具可安装完整版desktopsudoaptupdatesudoaptinstall-yros-humble-desktopros-humble-desktop包含核心库、Rviz、Gazebo、常用工具等体积较大但开箱即用。仅学习入门可先装ros-humble-ros-base。2.4 安装 colcon 与入门工具构建工具 colcon 是 ROS2 的标配sudoaptinstall-ypython3-colcon-common-extensions常用工具链视需要安装sudoaptinstall-yros-humble-ros2bag ros-humble-rviz2 python3-pip2.5 配置环境变量每次打开新终端都要source环境脚本很麻烦建议写进.bashrcechosource /opt/ros/humble/setup.bash~/.bashrcsource~/.bashrc如果你在 WSL2 中使用且需要图形界面Rviz、Gazebo可能需要启用 WSLgWindows 11 默认支持或配置 X11 转发。WSL2 通常已内置 WSLg直接在终端运行rviz2即可看到窗口。2.6 验证安装打开新终端依次输入# 方法一打印版本printenvROS_DISTRO# 方法二查看环境变量路径echo$ROS_DISTRO# 方法三查看已安装的可用包ls/opt/ros/humble/如果printenv ROS_DISTRO输出humble说明环境配置成功。你也可以先跑一个最简单的节点测试见下节。三、第一个 ROS2 程序Hello WorldROS2 程序的最小单元是节点Node。一个节点就是一个独立运行的进程它通过话题、服务、动作等方式与其他节点通信。本节我们写一个最基础的节点它只负责在启动时打印一句话以此理解节点的最小骨架。3.1 Python 版 Hello WorldrclpyPython 版最直观代码量最少。创建一个工作空间并新建一个包包的创建细节见第 3、4 篇这里先手动搭建最小结构# talker.py —— 一个最简的 Python 节点importrclpyfromrclpy.nodeimportNodeclassHelloNode(Node):def__init__(self):super().__init__(hello_node)self.get_logger().info(Hello, ROS2! 我是 Python 节点)defmain(argsNone):rclpy.init(argsargs)nodeHelloNode()try:rclpy.spin(node)exceptKeyboardInterrupt:passfinally:node.destroy_node()rclpy.shutdown()if__name____main__:main()运行这个脚本前需要先安装依赖。在已 source 环境的终端中python3-cimport rclpy# 若报错需安装 python3 依赖source/opt/ros/humble/setup.bash python3 talker.py你将看到日志输出Hello, ROS2! 我是 Python 节点同时进程会一直保持运行因为rclpy.spin()让节点不断处理回调。按CtrlC即可优雅退出。3.2 C 版 Hello WorldrclcppC 版结构更规范但需要CMakeLists.txt与package.xml。这里先给出核心源码完整包结构在第 3、4 篇讲解// hello_node.cpp —— 一个最简的 C 节点#includerclcpp/rclcpp.hppclassHelloNode:publicrclcpp::Node{public:HelloNode():Node(hello_node){RCLCPP_INFO(this-get_logger(),Hello, ROS2! 我是 C 节点);}};intmain(intargc,char**argv){rclcpp::init(argc,argv);autonodestd::make_sharedHelloNode();rclcpp::spin(node);rclcpp::shutdown();return0;}编译与运行假设已用 colcon 构建并 source# 构建colcon build --symlink-install --packages-select my_pkgsourceinstall/setup.bash# 运行ros2 run my_pkg hello_node同样你会看到Hello, ROS2! 我是 C 节点的日志。3.3 两种语言的关键差异对比上面两段代码可以快速抓住 rclcpp 与 rclpy 的编写差异维度C (rclcpp)Python (rclpy)头文件/导入#include rclcpp/rclcpp.hppimport rclpy初始化rclcpp::init(argc, argv)rclpy.init(argsargs)节点创建std::make_sharedNode()或继承Node继承rclpy.node.Node进入回调循环rclcpp::spin(node)rclpy.spin(node)退出清理rclcpp::shutdown()rclpy.shutdown()日志宏/方法RCLCPP_INFO(...)self.get_logger().info(...)管理方式智能指针需显式 spin对象自动生命周期C 更强调资源管理智能指针shared_ptr与显式控制性能更高、更适合实时与嵌入场景Python 上手快、开发效率高、适合原型验证与快速迭代。本系列将始终同时给出两种语言的示例。3.4 认识spin回调循环的本质无论是rclcpp::spin(node)还是rclpy.spin(node)其本质都是进入一个不断处理回调的循环。ROS2 节点是「事件驱动」的它平时挂起一旦有新的消息到达、定时器触发或服务请求进来就执行对应的回调函数。spin就是这个「等待并分发事件」的循环。如果你不再调用spin节点的回调永远不会被触发消息来了也处理不了。spin会一直阻塞直到收到CtrlC或shutdown信号。异步场景下也可用spin_some()轮询一次或单独管理一个SingleThreadedExecutor这在第 8 篇回调组章节会深入。四、理解节点的生命周期与日志4.1 节点的生命周期ROS2 节点有一个规范化的生命周期状态机第 26 篇硬件控制会用到但普通节点的大致流程是构造节点 → 注册功能话题/服务/定时器→ 进入 spin 回调 → 关闭清理。理解「构造期执行一次、回调期反复执行、关闭期清理资源」这个节奏是学好 ROS2 的关键。# lifecycle_demo.py —— 演示构造期与回调期的区别importrclpyfromrclpy.nodeimportNodeclassLifecycleDemo(Node):def__init__(self):super().__init__(lifecycle_demo)# 构造期只执行一次self.get_logger().info(构造期执行一次)self.count0# 创建一个定时器每 1 秒触发一次回调self.create_timer(1.0,self.on_timer)defon_timer(self):# 回调期每秒执行一次self.count1self.get_logger().info(f回调期执行第{self.count}次)defmain(argsNone):rclpy.init(argsargs)nodeLifecycleDemo()rclpy.spin(node)node.destroy_node()rclpy.shutdown()if__name____main__:main()运行后你会看到「构造期执行一次」只打一遍而「回调期执行第 N 次」每秒递增。4.2 日志级别与过滤ROS2 的日志系统支持分级过滤常见的日志级别为DEBUG、INFO、WARN、ERROR、FATAL。默认只显示INFO及以上。在 Python 中self.get_logger().set_level(rclpy.logging.LoggingSeverity.DEBUG)self.get_logger().debug(调试信息)self.get_logger().info(普通信息)self.get_logger().warn(警告)self.get_logger().error(错误)在 C 中RCLCPP_DEBUG(this-get_logger(),调试信息);RCLCPP_INFO(this-get_logger(),普通信息);RCLCPP_WARN(this-get_logger(),警告);RCLCPP_ERROR(this-get_logger(),错误);你也可以在命令行设置全局日志级别例如--ros-args --log-level DEBUG。4.3 命令行运行节点作为运行节点最常用的一条指令是# 运行某个包里的某个可执行节点ros2 runpackage_nameexecutable_name例如运行我们上面创建的节点ros2 run my_pkg hello_node。若只想看节点有哪些可执行文件可用ros2 pkg executablespackage_name五、实战组织一个小型节点项目为了让你把前面的零散概念串起来我们做一个「带定时器 命令行动态参数」的完整小项目。它会在定时器里持续输出计数并允许通过命令行参数覆盖节点名称。5.1 完整代码Python# timer_counter.py —— 定时计数器节点支持命令行参数importrclpyfromrclpy.nodeimportNodeclassTimerCounter(Node):def__init__(self):super().__init__(timer_counter)self.count0self.timerself.create_timer(0.5,self.on_timer)defon_timer(self):self.count1self.get_logger().info(f计数:{self.count})defmain(argsNone):rclpy.init(argsargs)nodeTimerCounter()rclpy.spin(node)node.destroy_node()rclpy.shutdown()if__name____main__:main()用命令行参数覆盖节点名称python3 timer_counter.py --ros-args--remap__node:my_counter此时ros2 node list中该节点会显示为/my_counter。--remap __node:xxx是 ROS2 中非常常用的重映射技巧。5.2 完整代码C// timer_counter.cpp#includerclcpp/rclcpp.hpp#includechronoclassTimerCounter:publicrclcpp::Node{public:TimerCounter():Node(timer_counter),count_(0){timer_this-create_wall_timer(std::chrono::milliseconds(500),std::bind(TimerCounter::onTimer,this));}private:voidonTimer(){count_;RCLCPP_INFO(this-get_logger(),计数: %d,count_);}intcount_;rclcpp::TimerBase::SharedPtr timer_;};intmain(intargc,char**argv){rclcpp::init(argc,argv);rclcpp::spin(std::make_sharedTimerCounter());rclcpp::shutdown();return0;}C 版同样可用--remap __node:my_counter重命名节点运行效果一致。5.3 节点管理常用指令完成本节后你应该能熟练使用以下命令来查看与操作节点# 查看当前所有活动的节点ros2nodelist# 查看某个节点的详细信息话题、服务、参数等ros2nodeinfo /timer_counter# 查看所有节点及其关联信息ros2nodelist-t六、总结本节我们完成了 ROS2 的入门理解 ROS2 与 ROS1 的架构区别、DDS 与 QoS 的概念、搭建 Humble 开发环境的基本流程并用 C 与 Python 两种语言写出了第一个 Hello World 节点。重点掌握ROS2 分布式中间件去中心化DDS 通信底座QoS 是核心。环境搭建Ubuntu 22.04 Humblesource /opt/ros/humble/setup.bash。节点是最小单元rclpy与rclcpp两种写法spin是回调循环。日志与生命周期构造期一次、回调期反复、关闭期清理。常用指令ros2 run、ros2 node list/info、--remap。下一篇预告下一节我们将正式认识「节点与 ROS 图」学习如何用ros2命令行、rqt 图形工具观察节点之间的连接关系理解节点、话题、服务之间是如何通过 ROS 图组织起来的并动手创建多个相互通信的节点。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门