ROS2 Humble 笔记(三)workspace 工作空间与 package 功能包
这篇博客是 B 站《古月·ROS2入门21讲》的第六个视频的图文记录,主要介绍了如何创建工作空间、功能包以及编译工作空间,但我在这里补充了一处如何创建 C++、Python 混用的功能包。原始视频链接如下:
- B 站视频链接:6.工作空间与功能包:开发过程的大本营
【Note】:该系列博客跳过了视频列表中的第五个,因为该视频介绍的是开发环境的配置,例如安装 git 和 vscode 之类,如果你想学习一下可以通过下面的链接查看:
- B 站视频链接:5.ROS2开发环境配置
工作空间
工作空间是 ROS 中一个非常重要的概念,在同一个工作空间中可以有多个不同的功能包。
1. 创建工作空间
这里为了和视频保持一致将工作空间命令也为 dev_ws(但我将工空间放在了 Desktop 目录下),在创建工作空间的时候你需要递归创建一个 src 文件夹放在里面:
$ mkdir -p dev_ws/src
然后进入到该工作空间的 src 目录下拉取源码,源码在古月居的 Github 仓库中:
- 古月居 Github 仓库:https://github.com/guyuehome/ros2_21_tutorials

$ cd dev_ws/src
$ git clone https://github.com/guyuehome/ros2_21_tutorials.git

如果你是刚开始使用这个环境,那么还需要安装一下 python-pip 工具,使用下面的命令安装:
$ sudo apt-get install python3-pip

【Note】:如果你按照我的博客顺序安装的 ros (即使用鱼香 ROS 一键安装命令),那么下面两行代码是不用执行的,如果你是按照 ROS 官方提供的命令则需要执行。
$ sudo pip3 install rosdepc
$ sudo rosdepc init & rosdepc update
2. 构建工作空间
2.1 安装依赖库
返回到工作空间根目录 dev_ws 后 执行下面的命令,该命令会自动查找你的工作空间中的包所需的依赖并自行安装:
$ rosdepc install -i --from-path src --rosdistro humble -y
显示以下内容表示依赖安装成功:

2.2 编译工作空间
先安装 colcon 工具,如果你之前用过 ROS1 的话会知道工作空间的构建工具是 catkin;colcon 是 ROS2 提供的一个优化后的构建工具:
$ sudo apt-get install python3-colcon-ros

在工作空间 dev_ws 目录下使用下面的命令编译工作空间:
$ colcon build
如果你在运行后出现以下报错:
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rosidl_adapter/resource/__init__.py", line 19, in <module>
import em
ModuleNotFoundError: No module named 'em'
Call Stack (most recent call first):
/opt/ros/humble/share/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake:130 (rosidl_adapt_interfaces)
CMakeLists.txt:25 (rosidl_generate_interfaces)

该报错通常是因为安装 ROS 是在安装 conda 之前,首先 删除 src 目录之前的所有文件删除,然后退出 conda 后重新编译:
(base) $ conda deactivate
$ colcon build

成功编译后在工作空间中会自动生成三个新的文件夹 build、install、log:

3. 配置环境变量
在工作空间 dev_ws 编译后生成的 install 目录下可以看到以下几个文件:

在当前终端中 source 其中的 local_setup.sh 即可让当前终端获得该工作空间下的环境变量:
$ source install/local_setup.sh

如果你想要在随便新开的一个终端中都能用该工作空间的功能包,那么需要将这个文件的 绝对路径 写入到 ~/.bashrc 文件中。但我个人 不推荐 这样做,原因如下:
- 该工作空间不能轻易移动:由于写入的绝对路径,如果你将工作空间移动到新的位置导致路径改变,那么新开的终端依旧找不到该工作空间;
- 存在重名功能包风险:如果你有多个工作空间,且没做好功能包命名管理,那么可能会存在重名的功能包使得想要运行的节点出现混乱;
功能包
功能包是工作空间的一个组件,一个功能包下面可以有多个节点。
【Note】:由于拉取的源码中已经有了同名功能包,直接执行创建命令后会报错,因此建议新开一个工作空间感受一下创建命令。
这里在先前的 dev_ws 同级目录下新建一个 exec_ws 工作空间:
$ mkdir -p exec_ws/src
$ cd exec_ws/src

【Note】:原视频在创建功能包时没有添加依赖包,但通常在创建时会加上参数 --dependencies 表示依赖包,如:
$ ros2 pkg create --build-type ament_cmake demo --dependencies rclcpp rclpy std_msgs
1 创建 python 功能包
如果你在该功能包中只使用 python 则用下面的命令创建:
$ ros2 pkg create --build-type ament_python learning_python

该功能包中有以下文件,核心是 setup.py 文件,该文件用来指明该包中有哪些脚本将被视作节点:

2 创建 C++ 功能包
如果你在该功能包中只使用 python 则用下面的命令创建:
$ ros2 pkg create --build-type ament_cmake learning_c

该功能包中有以下文件,核心是 CMakelists.txt 文件,该文件用来指明哪些 C++ 文件将被编译城节点:

3 创建 C++ 和 python 的混合功能包
【Note】:这部分内容原始视频中是没有的,只是因为我平时经常用到,所以添加到这里。
3.1 创建 C++ 基座功能包
因为 ament_cmake 是更通用的构建系统,它不仅可以编译 C++,还被设计为可以“调用” Python 的 setuptools 来处理包内的 Python 代码。纯 Python 包使用的 ament_python 则无法编译 C++。所以需要先用 ament_cmake 进行功能包构建,然后再添加依赖。
$ ros2 pkg create --build-type ament_cmake learning_mix

在该功能包下有以下文件:

3.2 创建 setup.py 文件
在该功能包中创建一个 setup.py 文件,该文件与 CMakeLists.txt 在同一级目录下,然后将以下内容写入,其核心内容与 1.3 中创建的纯 python 功能包中的 setup.py 文件一致,但要注意包名要修改:
from setuptools import find_packages, setup
package_name = 'learning_mix'
setup(
name=package_name,
version='0.0.0',
# 声明 Python 包的查找路径
packages=[package_name],
# 需要安装的数据文件(例如 package.xml, launch 文件等)
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
# 如果有 launch 文件
# ('share/' + package_name + '/launch', ['launch/my_launch.py']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='your_name',
maintainer_email='you@example.com',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
# ----------------------------------------------------
# 这是定义 Python 可执行文件的关键
# ----------------------------------------------------
entry_points={
'console_scripts': [
# 格式:'可执行文件名 = 模块路径:main函数'
# 'my_py_node = learning_mix.py_node:main',
],
},
)
3.3 创建 init.py 文件
在 exec_ws/src/learning_mix 目录下创建一个同名文件夹 leanring_mix 并添加一个空的 __init__.py 文件:
.
├── CMakeLists.txt
├── include
│ └── learning_mix
├── learning_mix <-- Python 模块放这里
│ └── __init__.py
├── package.xml
├── setup.py <-- 手动创建的 Python 配置文件
└── src <-- C++ 源代码放这里
4 directories, 4 files

4. 编译工作空间
此时三个功能包都创建完了,你的文件结构应该如下所示:

回到工作空间 exec_ws 目录下构建工作空间:
$ colcon build

如果你只想编译指定的某个包可以用 --packages-select 参数,这样就只会编译 leanring_python 这个包:
$ colcon build --packages-select leanring_python

更多推荐



所有评论(0)