ROS 入门第二讲:通信机制与工作空间
约 2876 字大约 10 分钟
2025-10-31
ROS 包索引主页访问:https://index.ros.org/
一、ROS 生态系统概览
| 组件 | 说明 |
|---|---|
| 发行版(Distribution) | Kinetic、Melodic、Noetic,每个版本对应特定 Ubuntu 版本 |
| 软件源(Repositories) | 官方与社区维护的功能包集合,通过 apt 安装 |
| ROS Wiki | 官方文档中心(wiki.ros.org),包含教程、API、功能包说明 |
二、ROS 核心架构
1. 节点(Node)——执行单元
- 是执行具体任务的独立进程(可执行文件)
- 可使用不同编程语言(C++、Python 等)编写
- 支持分布式部署:多个节点可运行在不同主机上
- 节点名称在系统中必须唯一
例如
turtlesim_node是一个可视化仿真节点,turtle_teleop_key是键盘控制节点。
2. ROS Master —— 控制中心
- 提供命名与注册服务,是节点通信的“中介”
- 核心功能:
- 跟踪所有活跃节点
- 记录话题(Topic)与服务(Service)的发布/订阅关系
- 协助节点之间建立直接通信连接
- 提供参数服务器(Parameter Server)
ROS Master 本身不传输数据,仅协助建立连接。数据在节点间直连传输。
三、ROS 通信机制
1. 话题(Topic)——异步通信
- 模型:发布/订阅(Publish/Subscribe)
- 特点:
- 发布者(Publisher)向话题发送消息
- 订阅者(Subscriber)接收消息
- 一对多、多对一、多对多均支持
- 无反馈机制,数据单向流动
- 消息可被缓冲(Queue)
消息(Message)
- 定义在
.msg文件中(如geometry_msgs/Twist.msg) - 包含字段名与数据类型(如
float64 x) - 编译后自动生成各语言的类/结构体
- 支持嵌套与自定义类型
图像、激光雷达数据、速度指令等常通过话题传输。
2. 服务(Service)——同步通信
- 模型:客户端/服务器(Client/Server)
- 流程:
- 客户端发送请求(Request)
- 服务端处理后返回响应(Response)
- 特点:
- 有明确反馈
- 阻塞式调用(同步)
- 一个服务只能有一个服务器,但可有多个客户端
服务定义
- 使用
.srv文件定义请求与响应结构 - 编译后生成对应语言的接口代码
示例:
/spawn服务用于在 turtlesim 中生成新海龟。
3. 动作(Action)
动作是服务的扩展,专为长时间运行任务设计
模型:增强版服务,支持长时间任务
特点:
- 异步 + 多阶段反馈(goal/status/feedback/result)
- 非阻塞:客户端发送 goal 后可继续执行其他操作。
- result 仅一次,feedback/status 可多次。
用途:耗时操作(如导航、抓取)
可取消、可监控进度。
通信通道:
| 通道 | 方向 | 说明 |
|---|---|---|
goal | Client → Server | 发起任务目标 |
cancel | Client → Server | 请求取消任务 |
status | Server → Client | 当前目标状态(如 PENDING, ACTIVE, SUCCEEDED) |
feedback | Server → Client | 周期性进度反馈(如“已移动 50%”) |
result | Server → Client | 最终结果(仅一次,任务结束时发送) |
4. 参数(Parameter)——全局配置字典
- 存储在 参数服务器(由 ROS Master 提供)
- 本质是一个键值对字典(Key-Value Store)
- 适用场景:
- 静态配置(如机器人尺寸、采样频率)
- 非二进制、小体积数据
- 不适用:频繁更新的动态数据(应使用话题)
可通过
rosparam命令行工具或代码读写参数。
通信机制对比
| 特性 | 话题(Topic) | 服务(Service) |
|---|---|---|
| 通信模式 | 发布/订阅 | 客户端/服务器 |
| 同步性 | 异步 | 同步 |
| 反馈机制 | 无 | 有(请求-响应) |
| 缓冲区 | 有(可设队列大小) | 无 |
| 实时性 | 较弱(适合流式数据) | 较强(适合命令/查询) |
| 节点关系 | 多对多 | 一对多(一个 Server) |
| 典型用途 | 传感器数据、状态广播 | 功能调用、配置修改 |
对比总结表
| 维度 | 话题(Topic) | 服务(Service) | 动作(Action) | 参数(Parameter) |
|---|---|---|---|---|
| 通信方向 | 单向 | 双向(请求-响应) | 双向(多通道) | 读写(非通信) |
| 同步性 | 异步 | 同步 | 异步 + 状态反馈 | 静态 |
| 反馈机制 | 无 | 一次响应 | status + feedback + result | 无 |
| 实时性 | 中(流式) | 高(阻塞) | 中高(可监控) | 无 |
| 任务时长 | 持续流 | 短任务(<秒级) | 长任务(秒~分钟) | 启动/配置时 |
| 节点关系 | 多对多 | 多客户端 / 1服务端 | 多客户端 / 1服务端 | 全局共享 |
| 是否阻塞 | 否 | 是 | 否 | 否 |
| 典型数据 | 传感器数据、状态 | 命令、查询 | 导航、抓取任务 | 配置参数 |
四、功能包(Package)
1. 功能包(Package)
- ROS 软件的基本单元
- 包含:
- 节点源代码(C++/Python)
- 消息/服务定义(
.msg/.srv) - 配置文件(如
.yaml参数文件) - 启动文件(
.launch) - 依赖声明
2. 功能包清单(Package Manifest)
- 文件:
package.xml - 记录:
- 包名、版本、作者、许可证
- 依赖项(build、run、test)
- 编译与运行所需信息
3. 元功能包(Metapackage)
- 用于组织相关功能包
- 本身不包含代码,仅作为“集合标签”
- 示例:
desktop-full包含可视化、仿真、导航等全套工具
五、常用 ROS 命令行工具
https://www.bilibili.com/video/BV1zt411G7Vn (P8)
运行小海龟
1. 可视化工具
rqt_graph # 实时查看节点与话题通信关系图2. 节点管理 rosnode
rosnode list # 列出所有活跃节点
rosnode info /turtlesim # 查看指定节点的详细信息(发布/订阅的话题等)3. 话题操作 rostopic
rostopic list # 列出所有话题
#rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist4. 消息与服务查看
rosmsg show geometry_msgs/Twist # 查看消息结构
rosservice list # 列出所有服务
rosservice call /spawn "x: 2.0 y: 2.0 theta: 0.0 name: 'turtle2'" # 调用服务5. 数据记录与回放(rosbag)
rosbag record -a -O cmd_record # 记录所有话题,保存为 cmd_record.bag
rosbag play cmd_record.bag # 回放记录的数据
.bag文件可用于调试、测试、数据集构建。
六、ROS 工作空间(Workspace)
ROS 工作空间的完整周期:创建 → 添加包 → 编译 → 配置 → 运行 → 开发
ROS 使用 Catkin 作为官方构建系统。标准 Catkin 工作空间结构如下:
my_workspace/ # 工作空间根目录(名称可自定义,如 catkin_ws)
├── src/ # 源代码空间(Source Space)— 放置所有功能包
│ └── your_package/ # 自定义或克隆的功能包
├── build/ # 编译中间文件(Build Space)— CMake 生成的临时文件
├── devel/ # 开发环境(Development Space)— 包含 setup.bash 等环境脚本
└── install/ # (可选)安装空间 — 使用 `catkin_make install` 生成建议:每个项目使用独立工作空间,避免包依赖冲突。
1. 创建工作空间
# 创建目录结构
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
# 初始化工作空间(生成 CMakeLists.txt)
catkin_init_workspace
catkin_init_workspace在 ROS Noetic 中已非必需(catkin_make会自动处理),但保留无害。
2. 编译工作空间
cd ~/catkin_ws
catkin_make- 首次编译会自动生成
build/和devel/目录。 - 后续修改代码后,只需再次运行
catkin_make即可增量编译。
3. 配置环境变量(关键)
编译后必须 source 环境脚本,才能让 ROS 找到你的包:
source ~/catkin_ws/devel/setup.bash验证是否生效:
echo $ROS_PACKAGE_PATH
# 应包含 ~/catkin_ws/src永久生效(推荐):
将 source 命令加入 ~/.bashrc,每次打开终端自动加载
打开文件写入:
gedit ~/.bashrc或者一键写入:
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc # 立即生效若同时使用多个工作空间,注意 source 顺序(后 source 的优先级更高)。
4. 添加功能包
通过 apt 安装官方包(推荐稳定包)
sudo apt install ros-noetic-rqt-robot-steering从 GitHub 克隆源码(适用于未发布或自研包)
cd ~/catkin_ws/src
git clone https://github.com/6-robot/wpr_simulation.git注意:部分源码包需手动安装依赖。例如:
cd ~/catkin_ws/src/wpr_simulation/scripts
./install_for_noetic.sh # 运行作者提供的依赖安装脚本5. 重新编译并运行
cd ~/catkin_ws
catkin_make
# 无需再次 source(若已写入 .bashrc)启动仿真:
roslaunch wpr_simulation wpb_simple.launch启动遥控器:
rosrun rqt_robot_steering rqt_robot_steering6. 在 VS Code 中开发
- 用 VS Code 打开整个
catkin_ws目录 - 按
Ctrl+Shift+B,选择 “catkin_make: build” - 确保
tasks.json中包含默认构建任务:
"group": {
"kind": "build",
"isDefault": true
},这样即可通过快捷键一键编译。
7. 创建自己的功能包
使用 catkin_create_pkg 快速创建模板:
cd ~/catkin_ws/src
catkin_create_pkg test_pkg rospy roscpp std_msgstest_pkg:包名rospy roscpp std_msgs:依赖项(根据实际需求添加)
包创建后,可在 test_pkg/src/ 中编写节点,在 test_pkg/CMakeLists.txt 和 package.xml 中管理依赖。
七、编写和使用 launch 文件
roslaunch 是 ROS 中用于批量启动节点、设置参数、管理依赖关系的核心工具。它基于 XML 语法,支持在一个 .launch 文件中启动多个节点、加载参数、嵌套其他 launch 文件,甚至条件启动。通过合理使用 launch 文件,你可以将复杂的多节点系统简化为一行命令,极大提升开发与部署效率。
优势:
- 自动启动
roscore(若未运行) - 无需手动逐个运行
rosrun - 支持参数化配置,便于复用和调试
1. launch 文件基本结构
标准 launch 文件以 .launch 为后缀,通常存放在功能包的 launch/ 目录下:
your_package/
└── launch/
└── example.launch基本语法遵循 XML 规范:
<launch>
<!-- 启动一个节点 -->
<node pkg="package_name" type="node_executable" name="node_name" output="screen" />
<!-- 设置参数 -->
<param name="camera_id" value="0" />
<!-- 包含其他 launch 文件 -->
<include file="$(find other_package)/launch/other.launch" />
</launch>说明:
<node>:启动 ROS 节点pkg:功能包名type:可执行文件名(对应CMakeLists.txt中注册的节点)name:运行时的节点名称(可重映射)output="screen":将日志输出到终端(默认输出到日志文件)
$(find pkg):ROS 特有语法,自动解析包路径
2. 创建并运行 launch 文件
步骤示例:
# 进入你的功能包
cd ~/catkin_ws/src/test_pkg
# 创建 launch 目录(若不存在)
mkdir -p launch
# 编写 launch 文件
gedit launch/simple.launchsimple.launch 内容示例:
<launch>
<node pkg="test_pkg" type="talker.py" name="my_talker" output="screen" />
<node pkg="test_pkg" type="listener.py" name="my_listener" output="screen" />
</launch>运行命令:
roslaunch test_pkg simple.launch注意:
- 无需提前运行
roscore——roslaunch会自动检测并启动- 若
roscore已在运行,则直接复用现有 master
3. 常用高级功能
(1) 传递参数(Arg)
<launch>
<arg name="robot_name" default="turtlebot" />
<param name="robot/name" value="$(arg robot_name)" />
<node pkg="robot_driver" type="driver_node" name="$(arg robot_name)_driver" />
</launch>运行时可覆盖默认值:
roslaunch test_pkg robot.launch robot_name:=my_robot(2) 条件启动(if / unless)
<arg name="use_sim" default="true" />
<node pkg="sensor_driver" type="real_sensor" name="sensor" if="$(eval not use_sim)" />
<node pkg="sensor_sim" type="sim_sensor" name="sensor_sim" if="$(arg use_sim)" />(3) 嵌套 Launch 文件
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="paused" value="true" />
</include>4. 最佳实践建议
- 每个功能包应包含独立的
launch/目录,组织清晰 - 避免硬编码路径,使用
$(find pkg)和<arg>提高可移植性 - 调试时加上
output="screen"查看实时日志 - 复杂系统可拆分为多个 launch 文件(如
bringup.launch,teleop.launch,rviz.launch),再通过主 launch 文件集成
5. 验证与调试技巧
查看当前运行的节点:
rosnode list查看参数服务器内容:
rosparam list若 launch 启动失败,检查:
- 节点可执行文件是否存在(
catkin_make是否成功?) CMakeLists.txt是否正确安装了可执行文件(install(TARGETS ...)或catkin_install_python(...))- 文件权限(Python 脚本需有可执行权限:
chmod +x script.py)
- 节点可执行文件是否存在(
提示:在 VS Code 中编辑
.launch文件时,可安装 ROS 扩展获得语法高亮和自动补全支持。
八、学习建议
- 使用
turtlesim熟悉节点、话题、服务 - 理解通信本质,话题适合“广播”,服务适合“问答”
- 善用工具,
rqt_graph、rostopic echo、rosnode info - 创建一个自己的工作空间
