3、ROS2基础入门:ROS2架构与核心概念、安装配置与第一个节点
说实话,每次带新人入门自动驾驶仿真,我都要先问一句:「ROS2 你熟不熟?」
很多人觉得 ROS2 就是个通信中间件,装个包、跑个节点就完事了。但我在实际项目中踩过太多坑——节点通信超时、话题数据丢帧、动作服务器卡死……说白了,都是基础概念没吃透。这一章,咱们就把 ROS2 的骨架搭起来。
3.1 ROS2 架构:从宏观到微观
ROS2 不是一个大而全的框架,它更像一套「乐高积木」。底层靠 DDS(数据分发服务)做实时通信,上层用节点、话题、服务、动作这些抽象概念来组织代码。
核心分层:
- 应用层:你的节点、话题、服务、动作代码
- 中间件层:DDS(Fast DDS / Cyclone DDS)负责数据序列化、发现、传输
- 操作系统层:Linux(推荐 Ubuntu 22.04)
我习惯把 ROS2 比作一个「智能物流系统」:节点就是仓库里的工人,话题是传送带(数据单向流动),服务是电话呼叫(一问一答),动作是复杂的流水线任务(有进度反馈)。
3.2 核心概念:节点、话题、服务、动作
3.2.1 节点(Node)
节点就是 ROS2 中的最小执行单元。每个节点负责一件事,比如「激光雷达驱动节点」只管发数据,「路径规划节点」只管算轨迹。
避坑指南: 我曾经把十几个功能全写在一个节点里,结果调试时根本分不清是哪个模块崩了。后来老老实实拆成独立节点,每个节点一个进程,崩溃了自动重启,省心多了。
3.2.2 话题(Topic)
话题是异步通信的通道。发布者往话题里扔数据,订阅者从话题里取数据。你想想看,这就像广播电台——发射塔不管谁在听,收音机也不管谁在发。
我的习惯: 话题命名用层级结构,比如 /sensor/lidar/points、/planning/trajectory。别用乱七八糟的名字,不然项目大了你自己都找不到。
3.2.3 服务(Service)
服务是同步的请求-响应模式。客户端发请求,服务端处理完返回结果。适合「查询当前车速」「设置目标点」这种一问一答的场景。
3.2.4 动作(Action)
动作是服务的升级版。它支持长时间执行的任务,并且能实时反馈进度。比如「导航到目标点」——你可以不断收到「已走30%」「已走60%」的反馈。
我在做自动泊车项目时,就用动作来控制车辆入库。客户端发一个「泊车目标」,服务端边执行边回报「方向盘角度」「剩余距离」,体验非常好。
3.3 ROS2 安装与配置
嗯,这里要注意版本匹配。ROS2 的版本和 Ubuntu 版本是绑定的。我用的是 ROS2 Humble + Ubuntu 22.04,稳定且社区活跃。
3.3.1 安装步骤(精简版)
# 1. 设置编码
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
# 2. 添加 ROS2 源
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -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 $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
# 3. 安装 ROS2 Humble(桌面版,包含 rqt 等工具)
sudo apt update
sudo apt install ros-humble-desktop
# 4. 设置环境变量
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc
注意: 如果你同时装了 ROS1 和 ROS2,千万别把两个 setup.bash 都 source 进同一个终端,会冲突。我建议开两个终端,各用各的。
3.4 编写第一个发布-订阅节点
理论说完了,咱们动手写代码。我习惯用 Python,调试快,适合教学。C++ 版本性能更好,但入门阶段 Python 完全够用。
3.4.1 创建功能包
# 创建工作空间
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
# 创建功能包
ros2 pkg create my_first_pkg --build-type ament_python --dependencies rclpy std_msgs
3.4.2 发布者节点(talker)
# my_first_pkg/my_first_pkg/talker.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class TalkerNode(Node):
def __init__(self):
super().__init__('talker')
self.publisher = self.create_publisher(String, 'chatter', 10)
self.timer = self.create_timer(1.0, self.timer_callback)
self.get_logger().info('Talker 节点已启动!')
def timer_callback(self):
msg = String()
msg.data = 'Hello, ROS2! 这是自动驾驶仿真环境。'
self.publisher.publish(msg)
self.get_logger().info(f'发布: {msg.data}')
def main(args=None):
rclpy.init(args=args)
node = TalkerNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
3.4.3 订阅者节点(listener)
# my_first_pkg/my_first_pkg/listener.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class ListenerNode(Node):
def __init__(self):
super().__init__('listener')
self.subscription = self.create_subscription(
String, 'chatter', self.listener_callback, 10)
self.get_logger().info('Listener 节点已启动,等待消息...')
def listener_callback(self, msg):
self.get_logger().info(f'收到: {msg.data}')
def main(args=None):
rclpy.init(args=args)
node = ListenerNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
3.4.4 配置 setup.py 并运行
# 在 setup.py 的 entry_points 中添加:
entry_points={
'console_scripts': [
'talker = my_first_pkg.talker:main',
'listener = my_first_pkg.listener:main',
],
},
# 编译并运行
cd ~/ros2_ws
colcon build
source install/setup.bash
ros2 run my_first_pkg talker # 终端1
ros2 run my_first_pkg listener # 终端2
看到两个终端互相打印消息了吗?这就是 ROS2 最基础的通信。我在第一次跑通时还挺激动的——虽然只是「Hello World」,但背后是整个分布式通信体系在运转。
3.5 使用 rqt 工具进行可视化调试
rqt 是 ROS2 的瑞士军刀。我调试节点时,90% 的问题靠 rqt 就能定位。
3.5.1 启动 rqt
# 安装(如果没装桌面版)
sudo apt install ros-humble-rqt*
# 启动
rqt
3.5.2 常用插件
| 插件名称 | 功能 | 我的使用场景 |
|---|---|---|
| Topic Monitor | 查看话题列表、发布频率、带宽 | 检查激光雷达数据是否丢帧 |
| Message Publisher | 手动发布话题消息 | 模拟传感器数据,测试下游节点 |
| Service Caller | 调用服务接口 | 调试路径规划服务的输入输出 |
| Plot | 实时绘制数据曲线 | 观察车辆速度、加速度变化 |
| Graph | 可视化节点-话题关系图 | 快速理清系统架构 |
小技巧: 用 rqt_graph 可以一键生成节点通信拓扑图。我曾经在一个 30 多个节点的项目里,靠这张图发现了一个「幽灵节点」——它订阅了话题但从不处理,白白占用带宽。
3.5.3 实战:用 rqt 调试我们的发布-订阅节点
- 启动 talker 和 listener 节点
- 打开 rqt,选择 Plugins → Topics → Topic Monitor
- 找到
/chatter话题,查看消息频率和内容 - 选择 Plugins → Topics → Message Publisher
- 手动向
/chatter发布一条消息,观察 listener 是否收到
你看,不用写一行代码,就能验证通信是否正常。这就是 rqt 的魅力。
好了,这一章的内容就到这里。ROS2 的基础概念、安装配置、第一个节点、rqt 调试工具,咱们都过了一遍。这些东西看着简单,但它们是整个仿真环境的基石。下一章我们会基于这些知识,搭建真正的传感器仿真模块。