3. 工作空间与功能包:搭建你的第一个ROS2项目

好,我们正式开始动手了。前两章我们把ROS2装好、环境配通,现在要解决一个核心问题:代码往哪放?怎么组织?

ROS2里,所有代码都跑在工作空间里。功能包则是代码的最小单元。说白了,工作空间是你的项目文件夹,功能包就是里面的一个个独立模块。

核心概念速览

  • 工作空间(Workspace):存放所有ROS2项目的顶层目录
  • 功能包(Package):包含节点、配置文件、依赖声明的最小单元
  • Colcon:ROS2的编译工具,替代了ROS1时代的catkin
ROS2 工作空间结构 my_robot_ws/(工作空间) src/(源码目录) ├── robot_bringup/ ├── robot_description/ ├── robot_navigation/ └── robot_sensors/ build/(编译中间文件) 自动生成,不用手动管 install/(安装产物) 编译后的可执行文件、库 log/(日志文件) 编译错误排查好帮手

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节点。