3. 工作空间与功能包:搭建你的第一个ROS2项目
好,我们正式开始动手了。前两章我们把ROS2装好、环境配通,现在要解决一个核心问题:代码往哪放?怎么组织?
ROS2里,所有代码都跑在工作空间里。功能包则是代码的最小单元。说白了,工作空间是你的项目文件夹,功能包就是里面的一个个独立模块。
核心概念速览
- 工作空间(Workspace):存放所有ROS2项目的顶层目录
- 功能包(Package):包含节点、配置文件、依赖声明的最小单元
- Colcon:ROS2的编译工具,替代了ROS1时代的catkin
3.1 创建工作空间
我个人习惯把工作空间放在 ~/ros2_ws 或者项目名命名的目录下。创建过程很简单,就三步:
# 1. 创建目录结构
mkdir -p ~/my_robot_ws/src
# 2. 进入工作空间
cd ~/my_robot_ws
# 3. 编译空工作空间(验证环境)
colcon build
第一次跑 colcon build 时,你会看到终端刷刷刷地输出信息。别慌,这是正常的。编译完成后,工作空间里会多出 build、install、log 三个目录。
我的小习惯:每次新建工作空间,我都会先跑一次 colcon build 空编译。这能快速确认ROS2环境变量有没有配好。如果这一步报错,八成是 ~/.bashrc 里的source路径写错了。
3.2 创建功能包
功能包是ROS2的灵魂。每个包都有自己的 package.xml 和 CMakeLists.txt(或 setup.py)。创建命令如下:
# 进入源码目录
cd ~/my_robot_ws/src
# 创建C++功能包
ros2 pkg create robot_bringup \
--build-type ament_cmake \
--dependencies rclcpp std_msgs
# 创建Python功能包
ros2 pkg create robot_control \
--build-type ament_python \
--dependencies rclpy std_msgs
这里我解释一下参数:
--build-type:指定编译类型。C++用ament_cmake,Python用ament_python--dependencies:声明依赖。比如rclcpp是C++的ROS2客户端库
注意:功能包名只能用小写字母、数字和下划线,不能用连字符。我曾经有个项目用了 robot-sensors 这种命名,结果编译时各种报错,排查了半天才发现是命名不规范的问题。
3.3 功能包的组织结构
创建完功能包后,我们来看看里面到底长什么样。以C++包为例:
robot_bringup/
├── CMakeLists.txt # 编译规则文件
├── package.xml # 包信息与依赖声明
├── include/ # 头文件目录
│ └── robot_bringup/
├── src/ # 源文件目录
│ └── main_node.cpp
└── launch/ # 启动文件目录(可选)
└── bringup.launch.py
Python包的结构略有不同:
robot_control/
├── package.xml # 包信息与依赖声明
├── setup.py # Python安装配置
├── setup.cfg # 安装路径配置
├── robot_control/ # Python模块目录
│ ├── __init__.py
│ └── control_node.py
└── resource/ # 资源文件
嗯,这里要注意 package.xml 这个文件。它是ROS2的"身份证",里面记录了包名、版本、作者、许可证和所有依赖。编译系统会读取它来解析依赖关系。
package.xml 核心字段
| 字段 | 说明 | 示例 |
|---|---|---|
<name> |
包名,必须与目录名一致 | robot_bringup |
<version> |
版本号,建议语义化版本 | 0.1.0 |
<description> |
简短描述包的功能 | 启动文件与节点管理 |
<license> |
开源许可证类型 | Apache-2.0 |
<depend> |
运行时依赖 | rclcpp |
<build_depend> |
仅编译时依赖 | ament_cmake |
3.4 Colcon 编译系统详解
Colcon 是ROS2的官方编译工具。它比ROS1的catkin更灵活,支持增量编译和并行编译。常用的命令就这几个:
# 编译整个工作空间
colcon build
# 只编译某个功能包(省时间)
colcon build --packages-select robot_bringup
# 编译并运行测试
colcon build --packages-select robot_bringup --cmake-args -DBUILD_TESTING=ON
# 清理编译产物
rm -rf build install log
我个人最常用的是 --packages-select。你想想看,一个大型机器人项目可能有几十个包,每次改一个文件就全量编译,那得等到天荒地老。只编译改动的包,效率能提升好几倍。
避坑指南:我曾经在编译时遇到 Could not find a package configuration file 的错误。排查了半天,发现是 package.xml 里漏写了某个依赖。记住:所有用到的库,都要在 package.xml 里声明,否则编译系统找不到它们。
3.5 环境配置与验证
编译完成后,别忘了source一下工作空间的环境变量:
# 每次新开终端都要执行
source ~/my_robot_ws/install/setup.bash
# 或者直接写进 ~/.bashrc 里
echo "source ~/my_robot_ws/install/setup.bash" >> ~/.bashrc
验证是否配置成功:
# 查看工作空间是否被识别
echo $AMENT_PREFIX_PATH
# 查看功能包是否被找到
ros2 pkg list | grep robot_bringup
如果能看到你的包名,说明一切正常。如果看不到,多半是source路径写错了,或者编译时出了错没注意到。
本章核心要点
- 工作空间 = src + build + install + log 四个目录
- 功能包是ROS2的最小单元,每个包有独立的
package.xml - Colcon 是编译工具,支持增量编译和选择性编译
- 每次新终端都要 source 工作空间的环境变量
好了,工作空间和功能包的基础知识就这些。说白了,这就是ROS2项目的"地基"。地基打牢了,后面盖楼才稳当。下一节我们会往功能包里写真正的代码——创建你的第一个ROS2节点。