🚀 ROS2 入门实战:跑通你的第一个节点

从"ROS 是什么"到"第一个节点跑起来" —— 零基础实战路线,参考西安交通大学笃行机器人队《ROS2 教程》整理
零基础 第一个节点 colcon 工作空间 小鱼一键安装 Zsh 终端优化
🎯 本页学习目标
1. 能用"人体/乐高"比喻向别人解释 ROS 是什么、不是什么
2. 能一眼分辨 ROS1 教程与 ROS2 教程(关键词 / 命令 / 库名)
3. 能独立完成:创建工作空间 → 创建功能包 → 写发布者 → colcon build → source → ros2 run → ros2 topic echo
4. 知道两个经典坑:不要把工作空间的 setup.bash 写进 .bashrc;ROS1/ROS2 命令混用
建议用时:60-90 分钟(含动手)

1 认识 ROS:一个生动的比喻

想象要造一个机器人,它需要:眼睛(摄像头/激光雷达)、大脑(决策电脑)、四肢(轮子/机械臂)、神经系统(线路与信号)。从零开始的话,换一个摄像头、加一个机械臂,整个通信系统可能都要重写。

💡 核心比喻:把构建机器人比作搭乐高 —— ROS 就是那一套标准尺寸的乐高积木块。它提供通信、驱动、算法库等基础模块和统一拼接标准,你只需专注"怎么搭"。
⚠️ 一个常见误区:ROS 名字里有"操作系统",但它不是 Windows/Ubuntu 那样的操作系统,而是运行在 Linux(主要是 Ubuntu)之上的"元操作系统"(meta-operating system)或软件框架。

2 核心概念:一张"人体类比"表

ROS 概念中文人体类比一句话解释
Node节点大脑功能区/器官一个个独立的可执行程序(如 camera_node 发图像、motor_control_node 控电机)
Topic话题广播频道节点间异步通信管道,发布/订阅一对多广播
Message消息语言/信号话题上传输的、有严格类型定义的数据
Service服务问答/请求一对一同步请求-响应,适合"重置里程计"这类短暂任务
Action动作布置任务并汇报进度带连续反馈的异步通信,适合"导航到 20 米外"这类长任务
Master主节点(仅 ROS1)总机/通信录注册中心,启动任何 ROS1 系统前必须先启动(ROS2 已去掉)

3 ROS1 vs ROS2:先学会"判别",再谈学习

网上海量教程仍是 ROS1 的,学习前先分清版本,否则会卡在各种报错里。

判别点ROS1(老)ROS2(新,推荐学这个)
核心架构中心化(依赖 Master,单点故障)去中心化(节点自动发现,DDS 通信)
搜索关键词务必加 "ROS 2" 或发行版名(Humble/Jazzy)
编译命令catkin_make / catkin buildcolcon build
Python 库import rospyimport rclpy
C++ 库#include "ros/ros.h"#include "rclcpp/rclcpp.hpp"
运行命令rosrun / rostopicros2 run / ros2 topic

4 安装与环境:小鱼一键安装 + 环境变量

国内用户强烈推荐 小鱼的一键安装脚本(支持 ROS Noetic / ROS2 Foxy / Humble 等):

wget http://fishros.com/install -O fishros && . fishros

安装后检查环境变量是否已写入 ~/.bashrc(或 ~/.zshrc):

source /opt/ros/humble/setup.bash   # ROS2 Humble(Ubuntu 22.04)
source ~/ros2_ws/install/setup.bash  # 你的工作空间(见下,别写进 .bashrc!)
⚠️ 经典坑:可以把全局/opt/ros/humble/setup.bash 写进 .bashrc,但千万不要把工作空间的 install/setup.bash 写进去—— 否则 ROS 环境被"写死"在一个工作空间,换项目时各种环境变量冲突。

验证:printenv | grep ROS 或直接敲 ros2 看是否有帮助信息。

5 终端优化:Zsh + Oh My Zsh(回报率极高)

ROS 命令又长又多,配一个强大的命令行环境非常值得。三步搞定:

1装 Zsh
sudo apt install zsh git curl -y
2装 Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
提示设默认 Shell 时选 Y
3装两个核心插件
zsh-autosuggestions(灰色自动建议,按 → 采纳)
zsh-syntax-highlighting(命令语法高亮,防输错)
git clone https://github.com/zsh-users/zsh-autosuggestions.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
# 编辑 ~/.zshrc,把 plugins=(git) 改为:
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
# 然后:
source ~/.zshrc   # 或 exec zsh

验证:新终端输入 ros2 topic list - 后按 Tab,应能看到参数补全提示。

6 实战:从零跑通第一个发布者节点

6.1 创建工作空间

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws

src 是源代码目录(关键字);功能包都放这里。

6.2 创建功能包

cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python --node-name simple_publisher my_first_package

--build-type ament_python 指定 Python 包(C++ 用 ament_cmake);--node-name 自动生成节点文件。生成的结构:

src/my_first_package/
├── my_first_package/
│   ├── __init__.py
│   └── simple_publisher.py   <- 节点代码在这
├── package.xml               <- 包清单(依赖/许可证)
├── setup.cfg
├── setup.py                  <- 入口点配置(见 6.4)
└── resource/

6.3 编写发布者代码

用编辑器打开 simple_publisher.py,替换为:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class MinimalPublisher(Node):
    def __init__(self):
        super().__init__('minimal_publisher')
        # 创建发布者:向 talker_topic 发 String 消息,队列长度 10(QoS 基础)
        self.publisher_ = self.create_publisher(String, 'talker_topic', 10)
        # 定时器:每 0.5 秒触发一次
        self.timer = self.create_timer(0.5, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = String()
        msg.data = 'Hello World: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1

def main(args=None):
    rclpy.init(args=args)
    minimal_publisher = MinimalPublisher()
    rclpy.spin(minimal_publisher)   # 保持运行,处理回调
    minimal_publisher.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

6.4 配置 setup.py 入口点

entry_points={
    'console_scripts': [
        'talker = my_first_package.simple_publisher:main',
    ],
},

意思是:创建名为 talker 的可执行脚本,运行它即执行包内模块的 main()

6.5 编译 → 激活 → 运行 → 验证

# ① 编译(在 ~/ros2_ws)
cd ~/ros2_ws
colcon build

# ② 激活环境(每个新终端都要先 source!)
source install/setup.bash

# ③ 运行节点(同一个已激活的终端)
ros2 run my_first_package talker
#    → [INFO] Publishing: "Hello World: 0" ... 每秒刷屏

# ④ 新开一个终端,先 source,然后验证:
source ~/ros2_ws/install/setup.bash
ros2 topic list          # 应看到 /talker_topic
ros2 topic echo /talker_topic   # 实时看到发布的消息
rqt_graph                # 可视化计算图:节点 → 话题
✅ 通关标准:两个终端分别运行 talker 与 ros2 topic echo,能看到实时消息流,rqt_graph 里出现 /minimal_publisher → /talker_topic 的连线 —— 你的第一个 ROS2 程序就跑通了!

7 命令行速查表(调试必备)

命令作用
ros2 run <包> <可执行>运行一个节点
ros2 node list列出所有运行中的节点
ros2 topic list / echo <话题>列出话题 / 实时监听消息(调试最常用)
ros2 topic pub <话题> <类型> '<数据>'从命令行发布一条消息
ros2 service list / call列出服务 / 调用服务
ros2 param list列出节点参数
ros2 bag record / play录制 / 回放话题数据(现场录数据回实验室重放调试)
rqt_graph / rqt_plot / rqt_console计算图可视化 / 数据曲线 / 日志过滤

8 本节自测

1. 下列哪个迹象说明你正在看的是 ROS1 教程?
💡 catkin 是 ROS1 的构建工具;ROS2 用 colcon。看到 rospy/rosrun/rostopic 也是 ROS1 标志。
2. 为什么"不要把工作空间的 install/setup.bash 写进 .bashrc"?
💡 全局的 /opt/ros/humble/setup.bash 可以进 .bashrc;工作空间的 setup.bash 应每次手动 source,避免环境被锁死。
3. ros2 topic echo 的作用是什么?
💡 ros2 topic echo 是调试最常用的命令;录制回放用 ros2 bag,列节点用 ros2 node list。
4. 关于 ROS 的说法,下列哪一项是正确的?
💡 见第 1 节「常见误区」:ROS 名字带「操作系统」但不是 Windows/Ubuntu 那样的操作系统,而是运行在 Linux 之上的元操作系统(meta-operating system)。Master 是 ROS1 的中心化组件,ROS2 已去掉(见第 2、3 节)。
5. 发布者代码里 self.create_publisher(String, 'talker_topic', 10) 的第三个参数「10」表示什么?
💡 见 6.3 代码注释:「队列长度 10(QoS 基础)」。定时器间隔是 0.5 秒(create_timer(0.5, ...)),与 10 无关。
6. 用 Python 创建 ROS2 功能包时,--build-type 应填哪个值?
💡 见 6.2:--build-type ament_python 指定 Python 包(C++ 用 ament_cmake)。catkin 是 ROS1 的构建工具,rosbuild 是更早期的构建方式——混用会卡在各种报错里(见第 3 节)。
📌 本节要点速查:①ROS 是运行在 Ubuntu 之上的「元操作系统」/软件框架,不是替代 Ubuntu 的操作系统;②分辨版本:ROS1 用 catkin_make/rospy/rosrun,ROS2 用 colcon build/rclpy/ros2 run;③工作空间的 install/setup.bash 不要写进 .bashrc,每个新终端手动 source;④八步跑通节点:建工作空间 → 建包(ament_python)→ 写发布者 → 配 entry_points → colcon build → source → ros2 run → ros2 topic echo;⑤调试最常用:ros2 topic list / echo、rqt_graph。
📌 本节小结:ROS 是"元操作系统",用乐高比喻最容易理解;学 ROS2 前先学会分辨 ROS1/ROS2(关键词/命令/库名);国内安装用小鱼一键安装;配好 Zsh 插件提升效率;按"建工作空间 → 建包 → 写代码 → 配入口点 → colcon build → source → ros2 run → ros2 topic echo"八步跑通第一个节点。
🤔 思考题: 1. 把发布者改成订阅者需要改哪几行?试着订阅 /talker_topic 并打印。
2. 为什么"每个新终端都要先 source"?这和 PATH 环境变量有什么关系?
3. 试着自己写一个 Service 节点,完成一次"问答"(提示:rclpy 的 create_service)。

9 参考来源