跳到主要内容

创建 ROS2 工作空间

什么是工作空间

ROS2 中的工作空间类似于开发文件夹,里面可以放置多个不同的功能包(package)。功能包就像是软件的最小单元,每个功能包负责特定的功能,例如机器人控制、传感器数据处理或导航算法等等。

在实际开发中,一般会基于 ROS2 的标准环境(称为“底层环境”或underlay)来创建一个自己的工作空间(称为“覆盖环境”或overlay)。覆盖环境允我们在底层环境之上添加新的功能包,甚至覆盖或修改已有的功能包。

简单地讲:

  • 底层环境(Underlay):这是 ROS2 系统默认安装的基础环境,比如你安装 ROS2 Jazzy后所在的目录 /opt/ros/jazzy
  • 覆盖环境(Overlay):这是你自己创建的工作空间环境,基于底层环境之上,可以自定义或者扩展已有的功能包。

创建工作空间目录

接下来,我们需要为新的工作空间创建一个专用的目录。工作空间的名称可以任意选择,但最好能够体现出其用途或目的。在此示例中,我们命名为 ros2_ws,表示“ROS2 工作空间”,并在其中创建子目录 src,该目录的名称是固定的,不能随便取,该目录用来存放功能包的源代码:

mkdir -p ~/ros2_ws/src

这里的 mkdir -p 命令可以一次性创建多级目录结构,确保创建工作空间时不会因为目录不存在而报错。

ROS2 工作空间结构

图 1: ROS 2 工作空间目录结构示意图

1. 加载 ROS 2 底层环境

为了可以在终端上使用底层环境,每次打开新终端时,都需要加载 ROS2 的底层环境,命令如下:

source /opt/ros/jazzy/setup.bash

加载底层环境后,即可在该终端中使用 ROS2 环境提供的各种功能。为避免每次打开终端时都需要手动输入上述命令,可以将该命令加入终端启动文件中:

echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc

.bashrc 是位于主目录 (~) 下的隐藏文件,用于配置每次打开新终端时自动执行的命令。

2. 使用colcon构建工作空间

在ROS 2开发中,“构建系统”和“构建工具”是两个相关但不同的概念:

  • 构建系统(例如ament_cmake、ament_python) 是底层机制,定义了单个功能包如何编译、链接和安装。

    • ament_cmake 基于CMake,提供了 ROS2 相关功能(如节点构建、接口生成)的额外宏和功能,适合C++项目。

    • ament_python 适用于Python编写的功能包,管理安装和依赖。

  • 构建工具(例如colcon) 是高层的管理工具,可以同时处理工作空间中的多个功能包,自动排序构建顺序,支持混合不同构建系统(如ament_cmake和ament_python)的功能包。 colcon还提供--symlink-install选项,使修改源代码时能立即生效(适用于python类型的功能包),无需重新构建和安装整个包,极大的提高了开发效率。

从 ROS2 工作空间的根目录(ros2_ws)运行colcon build命令以构建功能包。

colcon build

控制台将返回类似package finished的消息。

注意:是要在工作空间的根目录,即ros2_ws下编译。如果提示没有colcon build 可以使用如下语句安装:

sudo apt update
sudo apt install python3-colcon-common-extensions

colcon build的其他有用参数:

  • --packages-up-to 构建想要的功能包,加上它的所有依赖项,但不是整个工作空间(节省时间)

  • --symlink-install 在重新修改Python代码时,无需重新构建

  • --event-handlers console_direct+ 在构建时显示控制台输出(否则可以在log目录中找到)

  • --executor sequential 逐个处理功能包,而不是使用并行处理

一旦构建完成,在工作空间根目录(~/ros2_ws)的终端中输入命令:

ls

将看到colcon创建了新目录:

build  install  log  src

build 目录用于存放中间构建文件,例如 CMake 生成的文件、对象文件等,类似于 CMake 中的“构建缓存”,通常不需要手动操作此目录。install 目录存放最终构建完成后的可执行文件、库文件、消息接口文件等,用户可以使用它来加载覆盖层。log 保存构建过程的日志输出,包括每个功能包构建是否成功的详细信息。如果构建失败,可以通过查看这里的日志文件定位问题。

目录名作用说明
src/放置功能包源代码
build/编译中间文件和缓存
install/构建输出的可执行文件和库,加载运行环境的关键
log/构建过程的详细日志

3.加载覆盖层

在加载覆盖层之前,需要打开一个新的终端,与构建工作空间的终端分开。在同一终端中加载覆盖层,或在加载覆盖层的同一终端中构建,可能会造成复杂的问题。

在新终端中,首先加载底层环境,如果已经将下面命令写入了 ~/.bashrc 目录下,则不需要重新加载如下命令:


source /opt/ros/jazzy/setup.bash

进入工作空间的根目录,在根目录中,运行 source 命令加载刚才使用 colcon build 构建的工作空间:

cd ~/ros2_ws
source install/local_setup.bash

使用Python虚拟环境管理ROS 2依赖(可选)

为什么需要虚拟环境

在Ubuntu 24.04上,Python 功能包的依赖有时会和系统或其他工作空间的 Python 包冲突。为了避免这种冲突,可以为每个 ROS2 工作空间创建一个独立的 Python 虚拟环境(virtual environment),这样每个环境都有自己的 Python 解释器和包安装路径,不会影响系统环境或其他工作空间。

简单来说,虚拟环境可以保证:

  • 不影响系统Python和已有功能包;

  • 可以自由安装或升级Python库;

  • 每个工作空间独立管理依赖。

创建虚拟环境

在终端中,进入你希望存放虚拟环境的目录,例如~/ros2_env,然后执行:

mkdir -p ~/ros2_env
cd ~/ros2_env
python3 -m venv ros2

这里:

  • python3 -m venv ros2 表示创建名为ros2的虚拟环境;

  • 虚拟环境目录下会自动生成 bin/lib/include/ 等目录。

激活虚拟环境

每次在该虚拟环境中工作前,需要激活它:

source ~/ros2_env/ros2/bin/activate

激活后,终端提示符通常会显示 (ros2) 前缀,表示当前已经进入虚拟环境。

在虚拟环境中,Python命令和pip命令都只作用于该环境,不会影响系统Python:

python3 --version 
pip install <package_name>

安装ROS 2 Python依赖

如果你在虚拟环境中使用ROS 2 Python功能包,可以通过pip安装必要依赖。例如:

pip install colcon-common-extensions
pip install rclpy
pip install <其他Python库>

注意:ROS 2核心功能仍需通过系统ROS 2安装获得(例如/opt/ros/jazzy),虚拟环境只管理Python库,不替代系统ROS 2。

在虚拟环境中加载ROS 2环境

在每次新的终端中使用虚拟环境时,需要按顺序加载底层ROS 2环境和虚拟环境:

# 先加载ROS 2底层环境 
source /opt/ros/jazzy/setup.bash
# 激活虚拟环境
source ~/ros2_env/ros2/bin/activate
# 再进入工作空间加载覆盖层
cd ~/ros2_ws
source install/local_setup.bash`

这样,就可以在虚拟环境中安全使用Python功能包,同时仍能调用ROS 2的节点和工具。

退出虚拟环境

完成工作后,可以通过以下命令退出虚拟环境:

deactivate

终端提示符将恢复到默认系统环境。