本文是独立成篇的 ROS2 笔记,涵盖从命令行到仿真的全链路。建议配合 Ubuntu 22.04 + Humble 食用。
1. 什么是 ROS2?为什么要用它?
ROS 全称 Robot Operating System,它不是传统意义的操作系统 (像 Linux/Windows),而是一套运行在 Linux 上的 机器人软件框架:
-
硬件抽象: 屏蔽雷达、摄像头、IMU、电机驱动的底层差异
-
中间件: 提供标准化的节点间通信(类似你之前学的 MQTT,但更强大)
-
工具链: 调试、可视化(RViz2)、仿真(Gazebo)、录包(bag)
-
算法库: 导航 Nav2、建图 SLAM、MoveIt2 机械臂规划,开箱即用
不用 ROS2 的痛点:
假设机器人有 3个模块:激光雷达、摄像头、底盘控制,由3个团队开发。
-
没 ROS2:雷达团队写个 socket 发数据,摄像头团队写个串口,底盘团队写个 CAN,接口对不上,联调地狱。
-
有 ROS2:大家都说 Topic 普通话,雷达发
/scan,导航订阅/scan,底盘订阅/cmd_vel,即插即用。
2. ROS1 vs ROS2:一次颠覆性的重构

| 特性 | ROS1 (Noetic) | ROS2 (Humble/Iron) |
|---|---|---|
| 核心架构 | 中心化,必须有一个 roscore / Master 节点,Master挂了全挂 |
去中心化,无Master,基于 DDS 自动发现,无单点故障 |
| 通信中间件 | 自定义 TCPROS/UDPROS | DDS 标准(工业级,航空/国防在用) |
| 实时性 | 弱,TCP延迟不可控 | 强,DDS 可配置 QoS 实时策略 |
| 跨平台 | 主要 Linux | Linux/Windows/macOS/RTOS |
| 构建系统 | catkin | ament + colcon |
| Python | Python2 | Python3 |
| 节点生命周期 | 无,节点启动即运行 | 有,可配置 unconfigured/inactive/active/shutdown,适合产品 |
| 安全性 | 无加密 | SROS2 支持认证加密 |
一句话总结:ROS1 是实验室玩具,ROS2 是能上产线的商业系统。
3. ROS2 架构:五层分层模型

从底到顶:
-
DDS层 (Data Distribution Service): 厂商实现,Fast DDS(默认)、CycloneDDS、Connext。负责真正的网络传输,UDP多播/单播、共享内存。
-
RMW层 (ROS Middleware Interface): 抽象层,把不同厂商 DDS API 统一成一套标准接口
rmw_*。好处:今天用 Fast DDS,明天切 CycloneDDS,代码一行不改。 -
RCL层 (ROS Client Library): C语言实现的
rcl,封装节点、话题、服务等核心概念。 -
客户端库层:
rclcpp(C++)、rclpy(Python)、rcljava(Java) 等,面向开发者。 -
应用层: 你的节点、Nav2、MoveIt2。
所以 ROS2 删除 Master 后怎么发现彼此?
靠 DDS 的 SPDP + SEDP 自动发现:
-
新节点上线,DDS 向
239.255.0.1多播发广播:我来了,我有/scan发布器。 -
其他节点收到,回复我是谁我有什么订阅。
-
两边 QoS 兼容,则建立 P2P 直连,后续不经过任何中心。
4. 五大核心通信机制(嵌入式类比秒懂)

对于 STM32 开发者,用 FreeRTOS 类比:
| ROS2组件 | FreeRTOS类比 | 核心功能 | 通信模式 | 典型场景 |
|---|---|---|---|---|
| 节点 Node | 任务 Task | 最小功能单元 | - | 激光驱动、电机控制、路径规划各一个节点 |
| 话题 Topic | 消息队列 + 串口广播 | 连续数据流 | 异步、多对多 | 雷达发 /scan,相机发 /image_raw,底盘发 /odom |
| 消息 Message | struct 结构体 | 数据格式定义 | - | geometry_msgs/Twist 速度, sensor_msgs/LaserScan 雷达 |
| 服务 Service | 函数调用 + 问答 | 一次性远程调用 | 同步、一对一 | 拍照、查询电量、重置里程计 |
| 动作 Action | 状态机 + 带反馈任务 | 长时间可取消任务 | 异步 + 反馈 | 导航到目标点 NavigateToPose,可中途取消,看进度 |
| 参数 Parameter | Flash配置 + 全局变量 | 节点动态配置 | - | PID增益、最大速度,不重启即可修改 |
4.1 话题 Topic(最常用,80%场景)
publisher_node -- /scan (sensor_msgs/LaserScan) --> subscriber_node(s)
特点:解耦,发布者不知道谁在听,订阅者不知道谁发的。
4.2 服务 Service
客户端发 Request,等待服务端 Response。同步阻塞,但 ROS2 中是异步回调,不会卡死。
/client 请求 "计算路径" -> /planner 服务端 -> 返回路径
4.3 动作 Action(服务+话题的合体)
处理3秒以上的长任务:导航、机械臂抓取。
包含3部分:Goal目标 + Feedback周期反馈 + Result最终结果,且可取消。底层由3个话题+2个服务实现,但对你透明。
4.4 参数 + QoS
-
参数:
ros2 param set /turtlesim background_r 128动态改背景颜色,无需重启。 -
QoS:可靠性 RELIABLE / BEST_EFFORT,历史 KEEP_LAST,持久性 TRANSIENT_LOCAL 等,可针对雷达/图像/控制指令精细配置。
4.5 ROS2命令行操作
ROS2 90%的调试都靠命令行,掌握它就掌握了机器人的控制台。

| 命令族 | 常用命令 | 作用 |
|---|---|---|
ros2 node |
list, info /turtlesim, kill |
查看/杀死节点 |
ros2 topic |
list -t, echo /scan, hz /scan, bw, pub /cmd_vel ... |
调试连续数据流,最常用 |
ros2 service |
list -t, call /spawn ..., type, find |
调用一次性服务 |
ros2 action |
list, info /navigate_to_pose, send_goal |
调试导航等长任务 |
ros2 param |
list, get /node param, set, dump/load |
动态改参,运行时调PID |
ros2 interface |
show geometry_msgs/msg/Twist, list, proto |
查看消息结构 |
ros2 bag |
record -a, play, info |
录包回放,复现偶发Bug |
ros2 run |
run turtlesim turtlesim_node |
运行单个节点 |
ros2 launch |
launch nav2_bringup bringup_launch.py |
一键启动多节点 |
colcon |
colcon build --symlink-install, --packages-select |
编译工作空间 |
实战口诀:
# 不知道有什么? ros2 topic list -t # 看话题 ros2 node list # 看节点 ros2 service list # 看服务 # 不知道数据格式? ros2 interface show sensor_msgs/msg/LaserScan # 看数据流是否正常? ros2 topic echo /scan --no-arr # 不打超长数组 ros2 topic hz /scan # 看雷达频率是不是10Hz
5. ROS2开发环境配置
推荐组合:Ubuntu 22.04 + ROS2 Humble Hawksbill,LTS到2027年,最稳。
5.1 一键安装
sudo apt update && sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 sudo apt install software-properties-common -y sudo add-apt-repository universe sudo apt install curl gnupg lsb-release -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg 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 update sudo apt install ros-humble-desktop -y # 桌面完整版,含RViz2+Gazebo+示例 sudo apt install python3-colcon-common-extensions python3-rosdep ros-dev-tools -y # 环境变量 echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc # 初始化 rosdep sudo rosdep init || true rosdep update
5.2 多机隔离与工具
# 多机器人同WiFi防串台 export ROS_DOMAIN_ID=10 # 0~101,同一ID才能互通 # VSCode插件:ROS, URDF, 记得装 # Docker版(Windows/Mac用户) docker pull osrf/ros:humble-desktop验证:
ros2 run demo_nodes_cpp talker & ros2 run demo_nodes_py listener # 看到 hello world 互通即成功
6. 工作空间与功能包:开发过程的大本营

工作空间 Workspace 是项目的物理边界。官方推荐 ~/ros2_ws。
四个子目录:
-
src:放所有功能包源码,git clone都在里 -
build:colcon 编译中间文件,不用管 -
install:编译产物,setup.bash在这 -
log:编译日志
功能包 Package 是最小复用单元。包含 package.xml(依赖声明)+ CMakeLists.txt (C++) 或 setup.py (Python) + 代码。
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws/src # 创建C++包 ros2 pkg create my_cpp_pkg --build-type ament_cmake --dependencies rclcpp std_msgs # 创建Python包 ros2 pkg create my_py_pkg --build-type ament_python --dependencies rclpy std_msgs # 创建带消息定义的包 ros2 pkg create my_interfaces --build-type ament_cmake --dependencies rosidl_default_generators cd ~/ros2_ws rosdep install -i --from-path src --rosdistro humble -y colcon build --symlink-install source install/setup.bash
--symlink-install对Python极其重要,改.py不用重编,直接运行。
7. 节点:机器人的工作细胞
节点 Node 是 ROS2 最小执行单元,一个独立进程,只做一件事。
import rclpy from rclpy.node import Node class MyNode(Node): def __init__(self): super().__init__('my_first_node') # 节点名唯一 self.get_logger().info('Hello, 我是工作细胞!') self.timer = self.create_timer(1.0, self.tick) def tick(self): self.get_logger().info('心跳...') def main(): rclpy.init() rclpy.spin(MyNode()) # 阻塞,处理回调 rclpy.shutdown()
节点生命周期(ROS2 独有,产品级必用): unconfigured -> inactive -> active -> finalized,可通过生命周期管理器 lifecycle_manager 统一配置,机器人启动时先加载参数,再激活。
8. 话题:节点间传递数据的桥梁

话题 Topic 是异步、多对多广播,最常用。
/demonstration Publisher ---(/cmd_vel, geometry_msgs/Twist)---> Subscriber(s)
Python 发布者:
self.pub = self.create_publisher(Twist, '/cmd_vel', 10) msg = Twist() msg.linear.x = 0.2 self.pub.publish(msg)
订阅者:
self.sub = self.create_subscription(LaserScan, '/scan', self.scan_callback, 10) def scan_callback(self, msg): print(f'最前面障碍物距离: {msg.ranges[0]}')
命令行调试:
ros2 topic list -t ros2 topic echo /turtle1/pose ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5}, angular: {z: 0.5}}" -1
QoS 可选 RELIABLE/BEST_EFFORT,雷达用 BEST_EFFORT 少延迟,控制指令用 RELIABLE 保到达。
9. 服务:节点间的你问我答
服务 Service 是同步 一对一 请求响应,类似函数调用。
Client ---(Request: 拍照请求)---> Server Client <---(Response: 照片结果)--- Server
turtlesim 典型服务:
ros2 service list ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: 'turtle2'}"
代码:
from turtlesim.srv import Spawn self.client = self.create_client(Spawn, '/spawn') req = Spawn.Request(x=2.0, y=2.0, name='t2') future = self.client.call_async(req) rclpy.spin_until_future_complete(self, future)
适用: 重置里程计、保存地图、触发拍照等只需执行一次的任务。
10. 通信接口:数据传递的标准结构

所有话题/服务/动作的数据类型都有标准定义,放在 msg/srv/action 文件中。
Message (.msg): 话题载体
# Twist.msg Vector3 linear Vector3 angularService (.srv): 请求---响应
# AddTwoInts.srv int64 a int64 b --- int64 sumAction (.action): 目标---结果---反馈
# Fibonacci.action int32 order # Goal --- int32[] sequence # Result --- int32[] partial_sequence # Feedback
自定义接口:
# my_interfaces/msg/Student.msg string name int32 age # CMakeLists.txt rosidl_generate_interfaces(${PROJECT_NAME} "msg/Student.msg" "srv/AddTwoInts.srv" )
ros2 interface show就能看到。
11. 动作:完整行为的流程管理
Action = Service(可取消) + Topic(周期反馈)。处理长时间任务:导航、机械臂执行。
Client --Goal--> Server (开始去(2,2)) <--Feedback-- (已走30%) <--Feedback-- (已走80%) --Cancel--> (用户中途取消) <--Result-- (成功/失败/取消)
命令行:
ros2 action list ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: {pose: {position: {x: 2, y: 2}}}}"
Nav2 导航就是一个 Action Server,RViz2 点目标点就是 Client。
12. 参数:机器人系统的全局字典
参数 Parameter 是节点的 可动态配置变量,无需重启。
self.declare_parameter('kp', 1.0) kp = self.get_parameter('kp').value # 支持回调,参数一改,控制立刻生效 self.add_on_set_parameters_callback(self.param_callback)
命令行:
ros2 param list ros2 param get /turtlesim background_r ros2 param set /turtlesim background_r 200 ros2 param dump /turtlesim > params.yaml ros2 param load /turtlesim params.yaml
应用: 现场调小车最大速度、PID增益、相机曝光,直接 param set,不用重新编译烧录。
13. 分布式通信:多计算平台的任务分配

ROS2 原生支持分布式:
-
机器人端:Jetson Orin 跑激光+相机驱动
-
PC端:高性能主机跑建图、Nav2导航
-
只要同一局域网,同一
ROS_DOMAIN_ID,同一WiFi,节点自动发现,话题互通。
# 机器人端(192.168.1.10) export ROS_DOMAIN_ID=42 ros2 run rplidar_ros rplidar_composition # PC端(192.168.1.20) export ROS_DOMAIN_ID=42 ros2 topic echo /scan # 就能收到机器人雷达 rviz2 # 就能可视化
比 ROS1 需要 ROS_MASTER_URI 配置简单太多。
进阶:DDS 支持跨广域网、SROS2 加密,适合车队。
14. DDS:机器人的神经网络

DDS 是 ROS2 的底座,工业级标准。
-
Domain: 逻辑隔离域,
ROS_DOMAIN_ID就是 DDS Domain ID。 -
Participant: 每个进程一个 Participant。
-
Topic + DataWriter/DataReader: 底层真正收发。
-
QoS策略:
-
Reliability: RELIABLE/BEST_EFFORT
-
Durability: VOLATILE/TRANSIENT_LOCAL(新订阅者能否收到历史)
-
History: KEEP_LAST depth
-
RMW: ROS中间件接口层,抽象不同厂商 DDS。切换实现:
# 默认 Fast DDS export RMW_IMPLEMENTATION=rmw_fastrtps_cpp # 换 CycloneDDS,更轻量 sudo apt install ros-humble-rmw-cyclonedds-cpp export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
理解 DDS,调透 QoS,是解决 图像卡顿、控制丢包 的关键。
15. Launch:多节点启动与配置脚本

机器人启动要启动 10+ 节点:雷达、IMU、底盘、TF、RViz...一个个 ros2 run 会累死,Launch 一键搞定。
ROS2 Launch 是 Python 脚本,比 ROS1 XML 强大百倍,支持 if 判断、变量。
# my_robot/launch/robot.launch.py from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node(package='rplidar_ros', executable='rplidar_composition', parameters=[{'serial_port': '/dev/ttyUSB0', 'frame_id': 'laser'}]), Node(package='my_robot', executable='base_driver', output='screen'), Node(package='tf2_ros', executable='static_transform_publisher', arguments=['0','0','0.2','0','0','0','base_link','laser']), Node(package='rviz2', executable='rviz2', arguments=['-d', 'my.rviz']) ])
运行:ros2 launch my_robot robot.launch.py 带参:ros2 launch my_robot robot.launch.py use_sim_time:=true
16. TF:机器人坐标系管理器

机器人有无数坐标系:map 地图、odom 里程计、base_link 底盘、laser 雷达、camera_link。TF就是管理它们关系的 时变树。
-
TF 是话题
/tf和/tf_static -
每个变换都是
父坐标 -> 子坐标 + 时间戳 -
tf2可查询任意时刻任意两坐标系的关系。
ros2 run tf2_ros static_transform_publisher 0 0 0.2 0 0 0 base_link laser ros2 run tf2_tools view_frames # 生成PDF的TF树 rviz2 -> Add -> TF 看坐标轴
代码监听:
from tf2_ros import Buffer, TransformListener self.tf_buffer = Buffer() self.tf_listener = TransformListener(self.tf_buffer, self) trans = self.tf_buffer.lookup_transform('map', 'base_link', rclpy.time.Time())
没有 TF,导航、建图全崩。 必须保证TF树连通无环。
17. URDF:ROS机器人建模方法

URDF (Unified Robot Description Format) 用 XML 描述机器人 连杆 Link + 关节 Joint。
<robot name="my_car"> <link name="base_link"> <visual><geometry><cylinder length="0.1" radius="0.2"/></geometry></visual> </link> <link name="left_wheel"/> <joint name="left_wheel_joint" type="continuous"> <parent link="base_link"/><child link="left_wheel"/> <origin xyz="0 0.2 0"/><axis xyz="0 1 0"/> </joint> </robot>
-
link:外观visual、碰撞collision、惯性inertial -
joint:fixed固定、continuous连续旋转轮子、revolute有限转角舵机、prismatic滑轨 -
Xacro:URDF 宏,支持变量、计算,复杂机器人必用。
sudo apt install ros-humble-joint-state-publisher-gui ros2 launch urdf_tutorial display.launch.py model:=my_car.urdf # 在RViz里拖动滑杆,看关节运动
URDF + TF = 机器人完整数字孪生。
18. Gazebo:三维物理仿真平台

Gazebo 是独立的物理引擎,支持重力、摩擦、碰撞、光照、传感器仿真(雷达噪声、相机畸变)。
-
Gazebo 负责 让机器人动起来,有物理
-
Rviz 负责 把数据画出来,无物理
经典流程:
# 安装 sudo apt install ros-humble-gazebo-ros-pkgs ros-humble-gazebo-ros2-control # 启动仿真 ros2 launch my_robot gazebo.launch.py # 话题桥接:Gazebo的 /clock, /scan 会自动转 ROS2 话题
在URDF里加 <gazebo> 标签和插件,如 libgazebo_ros_diff_drive.so 差速驱动,Gazebo就开始仿真轮子转。
价值: 无需真机,在仿真中测试 Nav2 算法,撞烂了也不心疼。
19. Rviz:三维可视化显示平台
Rviz2 不模拟,只 订阅话题并可视化。
常用 Display:
-
RobotModel:显示URDF模型 -
LaserScan:雷达点云 -
PointCloud2:3D点云 -
Map:占据栅格地图 -
Path:导航路径 -
TF:坐标系 -
Image:相机图像
rviz2 # Add -> By topic -> 勾选 /scan # 配置文件保存 .rviz,下次一键加载
配合 Nav2,Rviz里可点 2D Pose Estimate 初始位姿,2D Goal Pose 导航目标。
20. RQT:模块化可视化工具
RQT 是基于 Qt 的插件容器,集成几十个小工具:
rqt # 打开插件选择器 rqt_graph # 节点图,最常用,看话题连接(上一章用过) rqt_plot # 画曲线,/odom速度波形 rqt_console # 日志过滤 rqt_reconfigure # 动态调参图形化前端 rqt_bag # 播放 bag 包
安装:sudo apt install ~nros-humble-rqt*
调试三件套:rqt_graph + ros2 topic echo + rviz2。
21. ROS2应用与进阶攻略
到此,你已学完 ROS2 核心。下一步:
应用层
-
导航 Nav2:
sudo apt install ros-humble-navigation2,SLAM建图slam_toolbox,定位amcl,一键导航。 -
机械臂 MoveIt2: 抓取规划。
-
ros2_control: 统一硬件接口,你的 STM32 底盘写一个
hardware_interface,就能被 Nav2 调度。 -
micro-ROS: 在 STM32F4/H7 上直接跑 ROS2 节点,不再经串口转发,订阅
/cmd_vel成为真·ROS2节点。
进阶路线图
-
动手造小车: 差速底盘 + RPLIDAR A1 + IMU,跑通
URDF -> Gazebo -> Nav2全流程。 -
视觉:
v4l2_camera+OpenCV+YOLO,话题/image_raw→ 目标检测。 -
多机协同: 两台机器人同
ROS_DOMAIN_ID,Nav2支持多机编队。 -
云边端: ROS2 + MQTT桥,机器人数据上阿里云,参考你之前 MQTT 篇。
最终建议:
-
先把 turtlesim + 话题服务 玩熟
-
再用 URDF + Rviz 搭自己模型
-
再进 Gazebo 仿真 + Nav2 导航
-
最后 接真车
总结
本篇严格目录,独立介绍了 ROS2 的命令行、环境、工程、五大通信、DDS、Launch、TF、URDF、Gazebo、Rviz、RQT。
工具包:Humble官方文档 + 鱼香ROS《ROS2机器人开发从入门到实践》 + 古月居教程