
这次我们来看一个 ROS2 机器人开发的自学笔记分享项目。对于想入门机器人操作系统ROS第二代的开发者来说最头疼的往往不是概念本身而是如何将零散的知识点串联成一套可执行、可落地的学习路径。这份手写笔记的价值就在于它跳过了官方文档的庞杂直接提炼了从环境搭建、核心概念到实际项目开发的关键步骤和常见“坑点”。它的核心特点非常明确实战导向、避坑指南、结构清晰。笔记内容不是简单的概念罗列而是围绕“如何让一个机器人真正动起来”这一目标展开涵盖了 ROS2 的核心通信机制、常用工具、仿真环境搭建以及真实的代码示例。对于自学者而言它能帮你快速建立知识框架避开初期部署和环境配置中的大量陷阱把精力集中在理解机器人开发的本质上。本文将基于这份宝贵的自学笔记为你梳理出一条高效的 ROS2 入门与实践路线。我们会重点关注学习路线的规划、Ubuntu 环境的准备与 ROS2 的安装、核心概念节点、话题、服务、动作的代码级理解、Gazebo/Webots 仿真入门以及如何将所学应用于一个简单的移动机器人控制项目。无论你是在校学生、机器人爱好者还是寻求转型的工程师这篇文章都能提供一套即拿即用的学习框架和问题排查清单。1. 核心能力速览笔记价值分析这份手写笔记并非一个可执行的软件项目而是一份高度凝练的学习指南和知识图谱。它的“能力”体现在对学习过程的优化上。能力项说明与价值内容形式手写整理笔记非代码仓库侧重于知识梳理与经验总结。核心目标降低 ROS2 自学门槛提供清晰、线性的学习路径重点标注易错点。覆盖范围从 Linux/Ubuntu 基础、ROS2 安装Humble/Foxy、核心概念、CLI 工具、编程Python/C到仿真Gazebo与简单实践。硬件门槛无特殊要求。推荐使用 x86 架构的电脑安装 Ubuntu 22.04 LTS 或 20.04 LTS 系统。支持在虚拟机或物理机中运行。“启动”方式按照笔记规划的章节顺序进行学习与实践。主要产出帮助学习者建立系统的 ROS2 知识体系并能独立完成基础机器人仿真与控制程序的开发。适合场景ROS2 零基础入门、课程学习补充、项目开发前期快速回顾、面试知识点梳理。2. 适用场景与使用边界这份笔记是一份学习加速器和避坑地图但它不能替代官方文档和动手实践。它最适合谁完全零基础的机器人开发爱好者不知道从何开始被官方教程的广度吓到。有 ROS1 基础想转向 ROS2 的开发者需要快速了解 ROS2 的差异和新的最佳实践。高校学生用于课程学习、完成作业或毕业设计需要一条被验证过的学习路径。寻求技能拓展的软件工程师希望将机器人技术作为新的技能分支。它能解决什么问题路径迷茫提供“先学什么后学什么”的明确顺序。环境陷阱指出安装 ROS2 时常见的依赖、版本、源配置错误。概念抽象用比喻和代码示例解释节点、话题、服务等核心概念。工具生疏介绍ros2 run,ros2 topic list,rviz2,rqt等关键工具的实际用法。仿真入门指导如何利用 Gazebo 或 TurtleBot3 仿真进行第一次“无实物”机器人编程。它的边界在哪里不是代码库它提供代码片段和思路但不是完整的、可编译的项目仓库。最终项目需要你自己创建。不是最新动态ROS2 版本在迭代笔记内容可能基于某个特定版本如 Humble Hawksbill。学习时需注意与当前官方文档的细微差别。不涉及高级主题如导航栈Nav2、MoveIt2机械臂控制、ROS2 中间件深度定制等复杂主题通常需要在此基础上进行专项学习。需要动手配合绝对不能只看不练。笔记的价值必须在跟随其步骤敲代码、跑例子的过程中才能完全体现。3. 环境准备与前置条件在跟随笔记学习之前你必须准备好一个可用的 ROS2 开发环境。这是所有实践的基础。1. 操作系统Ubuntu Linux首选Ubuntu 22.04 LTS (Jammy Jellyfish)。这是当前 ROS2 Humble Hawksbill 的官方支持版本也是长期支持版社区资源最丰富。备选Ubuntu 20.04 LTS (Focal Fossa)。对应 ROS2 Foxy Fitzroy也是一个长期支持版本。部署方式物理机安装性能最佳兼容性最好。建议为 ROS2 开发单独准备一台电脑或一个硬盘分区。虚拟机如 VMware, VirtualBox适合在 Windows/macOS 主机上体验。需要为虚拟机分配足够资源建议至少4核CPU8GB内存40GB磁盘。WSL2 (Windows Subsystem for Linux)在 Windows 10/11 上获得接近原生 Linux 的体验。推荐使用 Ubuntu 22.04 on WSL2。注意WSL2 对图形界面和 USB 设备如机器人硬件的支持需要额外配置。2. 系统基础配置终端熟悉 Linux 基本命令cd,ls,mkdir,sudo,apt等。软件源将 Ubuntu 软件源切换到国内镜像如阿里云、清华源可以大幅提升软件安装速度。# 备份原有源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak # 编辑源列表以清华源为例Ubuntu 22.04 sudo sed -i s//.*archive.ubuntu.com//mirrors.tuna.tsinghua.edu.cng /etc/apt/sources.list sudo sed -i s//.*security.ubuntu.com//mirrors.tuna.tsinghua.edu.cng /etc/apt/sources.list # 更新软件包列表 sudo apt update sudo apt upgrade -y区域设置确保系统语言和区域设置正确避免后续编译出现奇怪的字符编码错误。sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALLen_US.UTF-8 LANGen_US.UTF-8 export LANGen_US.UTF-83. 必备工具安装在安装 ROS2 之前先安装一些基础开发工具。sudo apt install -y curl wget git build-essential cmake python3-pip python3-rosdep2 python3-colcon-common-extensions4. ROS2 安装部署与验证笔记中通常会强调选择正确的 ROS2 版本。这里以ROS2 Humble (Ubuntu 22.04)为例展示标准安装流程。1. 设置 Locale 和软件源确保已完成上一节中的区域设置和软件源更换。2. 添加 ROS2 软件源# 确保 Universe 仓库已启用 sudo apt install software-properties-common sudo add-apt-repository universe # 添加 ROS2 GPG 密钥 sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg # 将 ROS2 仓库添加到源列表 echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release echo $UBUNTU_CODENAME) main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null # 更新软件包列表 sudo apt update3. 安装 ROS2 桌面版桌面版包含核心库、工具、教程和图形化界面工具最适合学习和开发。sudo apt install -y ros-humble-desktop4. 配置环境变量安装完成后每次打开新终端都需要 source ROS2 的安装脚本才能使用ros2命令。# 对于 bash 用户 echo “source /opt/ros/humble/setup.bash” ~/.bashrc source ~/.bashrc # 对于 zsh 用户 echo “source /opt/ros/humble/setup.zsh” ~/.zshrc source ~/.zshrc5. 安装自动补全可选但强烈推荐sudo apt install -y python3-argcomplete ros2 run demo_nodes_cpp talker --ros-args --log-level info # 运行一次以初始化6. 验证安装运行两个经典示例节点测试通信是否正常。终端1发布者ros2 run demo_nodes_cpp talker你应该看到持续输出的“Hello World: 计数”消息。终端2订阅者ros2 run demo_nodes_py listener你应该看到持续输出的“I heard: [Hello World: 计数]”消息。如果两个终端能正常收发消息恭喜你ROS2 基础环境安装成功笔记中关于安装的“坑点”通常集中在网络超时、密钥错误、版本不匹配等问题上按照上述步骤一般可以避免。5. 核心概念实战与代码验证笔记的精髓在于将抽象概念转化为可运行的代码。我们选取几个核心概念进行实战验证。5.1 创建工作空间与功能包这是所有 ROS2 项目的起点。# 1. 创建并进入工作空间目录 mkdir -p ~/ros2_ws/src cd ~/ros2_ws # 2. 编译空工作空间初始化 colcon build # 3. 创建 Python 功能包 cd src ros2 pkg create --build-type ament_python my_first_package --dependencies rclpy # 4. 返回工作空间根目录并编译 cd ~/ros2_ws colcon build --packages-select my_first_package # 5. 激活工作空间环境 source install/setup.bash5.2 编写一个简单的发布者节点在~/ros2_ws/src/my_first_package/my_first_package/目录下创建文件minimal_publisher.py。#!/usr/bin/env python3 import rclpy from rclpy.node import Node from std_msgs.msg import String import time class MinimalPublisher(Node): def __init__(self): super().__init__(minimal_publisher) self.publisher_ self.create_publisher(String, topic, 10) timer_period 1.0 # 秒 self.timer self.create_timer(timer_period, self.timer_callback) self.i 0 def timer_callback(self): msg String() msg.data fHello World: {self.i} self.publisher_.publish(msg) self.get_logger().info(fPublishing: {msg.data}) self.i 1 def main(argsNone): rclpy.init(argsargs) minimal_publisher MinimalPublisher() rclpy.spin(minimal_publisher) minimal_publisher.destroy_node() rclpy.shutdown() if __name__ __main__: main()设置可执行权限并编译chmod x ~/ros2_ws/src/my_first_package/my_first_package/minimal_publisher.py cd ~/ros2_ws colcon build --packages-select my_first_package source install/setup.bash5.3 编写一个简单的订阅者节点在同一目录下创建文件minimal_subscriber.py。#!/usr/bin/env python3 import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalSubscriber(Node): def __init__(self): super().__init__(minimal_subscriber) self.subscription self.create_subscription( String, topic, self.listener_callback, 10) self.subscription # 防止未使用变量警告 def listener_callback(self, msg): self.get_logger().info(fI heard: {msg.data}) def main(argsNone): rclpy.init(argsargs) minimal_subscriber MinimalSubscriber() rclpy.spin(minimal_subscriber) minimal_subscriber.destroy_node() rclpy.shutdown() if __name__ __main__: main()同样设置权限并编译。5.4 功能测试与效果验证测试目的验证自定义的发布者和订阅者节点能否正常通信。启动发布者source ~/ros2_ws/install/setup.bash ros2 run my_first_package minimal_publisher预期结果终端每秒打印一次“Publishing: ‘Hello World: X’”。启动订阅者新开终端source ~/ros2_ws/install/setup.bash ros2 run my_first_package minimal_subscriber预期结果终端每秒打印一次“I heard: ‘Hello World: X’”且 X 与发布者同步。使用命令行工具观察再开一个终端# 查看活跃节点 ros2 node list # 查看活跃话题 ros2 topic list # 实时查看话题内容 ros2 topic echo /topic # 查看话题发布频率 ros2 topic hz /topic判断成功标准订阅者能准确接收并打印发布者发出的每一条消息且ros2 topic list中能看到/topic。这证明你成功创建了功能包、编写了节点、理解了话题通信模型。6. 仿真环境入门Gazebo 与 TurtleBot3理论学习后在仿真环境中控制一个虚拟机器人是极佳的实践。笔记通常会引导你完成这一步。1. 安装 TurtleBot3 仿真相关包sudo apt install -y ros-humble-gazebo-ros-pkgs ros-humble-turtlebot3-gazebo ros-humble-turtlebot3-description ros-humble-turtlebot3-teleop2. 设置 TurtleBot3 模型类型echo “export TURTLEBOT3_MODELburger” ~/.bashrc source ~/.bashrc3. 启动 Gazebo 仿真世界ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py如果一切顺利Gazebo 图形界面将打开显示一个包含 TurtleBot3 Burger 机器人的仿真环境。4. 控制机器人移动方式一键盘控制新终端source ~/.bashrc ros2 run turtlebot3_teleop teleop_keyboard根据终端提示如w/a/s/d/x控制机器人前进、转向、停止。方式二查看传感器数据新终端# 查看激光雷达数据 ros2 topic echo /scan # 查看摄像头图像需要安装 image_view sudo apt install ros-humble-image-view ros2 run image_view image_view image:/camera/image_raw5. 编写简单控制节点巩固知识创建一个新的功能包和节点让机器人自动做圆周运动而不是手动控制。这会将之前学的发布/订阅与服务调用结合起来。# ~/ros2_ws/src/my_robot_controller/my_robot_controller/circle_driver.py #!/usr/bin/env python3 import rclpy from rclpy.node import Node from geometry_msgs.msg import Twist import math class CircleDriver(Node): def __init__(self): super().__init__(circle_driver) self.publisher_ self.create_publisher(Twist, /cmd_vel, 10) timer_period 0.1 # 秒 self.timer self.create_timer(timer_period, self.timer_callback) self.start_time self.get_clock().now() def timer_callback(self): msg Twist() # 设置线速度和角速度使机器人画圆 msg.linear.x 0.2 # 前进速度 0.2 m/s msg.angular.z 0.5 # 旋转速度 0.5 rad/s self.publisher_.publish(msg) # 运行10秒后停止 if (self.get_clock().now() - self.start_time).nanoseconds 10e9: msg.linear.x 0.0 msg.angular.z 0.0 self.publisher_.publish(msg) self.get_logger().info(Circle driving finished.) rclpy.shutdown() def main(argsNone): rclpy.init(argsargs) circle_driver CircleDriver() rclpy.spin(circle_driver) if __name__ __main__: main()编译并运行此节点确保 Gazebo 仿真正在运行你将看到 TurtleBot3 开始自动转圈。7. 资源占用与性能观察在仿真和开发过程中了解系统资源占用情况很重要。查看 ROS2 节点进程使用top或htop命令可以看到各个节点如gazebo,teleop_keyboard, 你的自定义节点的 CPU 和内存占用。Gazebo 资源占用Gazebo 仿真器本身是资源消耗大户尤其是开启复杂模型和传感器时。首次启动可能较慢。在虚拟机中运行 Gazebo 需要分配足够的 CPU 核心和内存。网络通信负载使用ros2 topic bw /topic_name可以查看某个话题的数据带宽。这对于评估传感器数据流如图像、点云的负载很有帮助。降低资源消耗的建议在不需要可视化时可以使用headless模式启动 Gazebo-s参数。开发调试时使用--log-level调整日志级别避免输出过多调试信息。合理设计话题的 QoS服务质量策略例如对于不重要的状态信息可以使用Best Effort策略而非Reliable。8. 常见问题与排查方法自学路上 90% 的时间都在解决问题。以下是笔记中可能总结的典型问题及排查思路。问题现象可能原因排查方式解决方案ros2命令未找到环境变量未正确配置echo $ROS_DISTRO确认已执行source /opt/ros/humble/setup.bash并添加到~/.bashrccolcon build失败提示缺少依赖功能包的依赖未安装查看编译错误信息通常包含缺失的包名使用rosdep安装rosdep install -i --from-path src --rosdistro humble -y自定义节点编译成功但ros2 run找不到工作空间环境未激活echo $AMENT_PREFIX_PATH在运行节点前先source ~/ros2_ws/install/setup.bashGazebo 启动黑屏或卡住显卡驱动/OpenGL 问题查看终端 Gazebo 启动日志1. 安装推荐显卡驱动。2. 尝试软件渲染export LIBGL_ALWAYS_SOFTWARE1节点启动后立即退出Python 脚本权限问题或 shebang 错误ls -l 脚本路径检查权限检查脚本第一行是否为#!/usr/bin/env python3chmod x 脚本路径添加执行权限话题无法通信1. 话题名称不匹配2. 数据类型不匹配3. 节点未运行1.ros2 topic list核对话题名。2.ros2 interface show msg_type核对消息结构。3.ros2 node list确认节点已启动。1. 统一发布和订阅的话题名。2. 确保使用的消息类型完全一致。3. 检查节点启动日志。sudo rosdep init失败网络问题无法访问 raw.githubusercontent.comcurl -I https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list1. 使用代理或更换网络环境。2. 手动创建文件网上有相关教程。9. 最佳实践与学习建议结合笔记的精华给出以下学习与开发建议循序渐进勿贪多严格按照“环境搭建 - 核心概念节点、话题、服务、动作- 工具使用CLI, rqt, rviz2- 仿真入门 - 项目实践”的路径。在完全理解前一个环节前不要急于跳入下一个。动手重于阅读对于每一个概念都亲手敲一遍代码运行一遍例子。即使是从笔记或教程里复制粘贴也要尝试修改参数观察变化。善用官方文档与社区笔记是地图官方文档 docs.ros.org 是百科全书。遇到问题时错误信息是最好的线索先尝试自己搜索Google/Stack Overflow/ROS Answers。版本管理使用 Git 管理你的工作空间代码。为每个实验或项目创建独立的分支。模块化开发将不同的功能如感知、决策、控制拆分成独立的功能包降低耦合度。日志与调试合理使用self.get_logger().info()等日志语句。利用rqt_graph可视化节点和话题的连接关系这是调试通信问题的利器。仿真先行在将代码部署到真实机器人之前务必在 Gazebo 等仿真环境中进行充分测试避免硬件损坏。加入社区关注 ROS 相关的论坛、Discord 频道或线下活动与其他开发者交流是快速成长的最佳途径。这份“能救一个是一个”的手写笔记其最大价值在于它源自实践者的真实学习历程过滤了噪音直击要害。它告诉你哪些是必须掌握的核心哪些坑可以提前避开。学习 ROS2 就像学习一门新的语言初期语法概念和工具命令行可能枯燥但一旦你能让仿真世界里的机器人按照你的指令运动起来那种成就感会驱动你探索更广阔的机器人技术世界。从今天起打开终端创建你的第一个功能包让“Hello World”在机器人话题中传递这就是你机器人开发之旅的坚实第一步。