3. ROS2实战:工作空间创建、包管理、编译系统与调试工具
好,咱们直接进入正题。ROS2 是自动驾驶中间件的核心底座,这一点我想你已经听了很多遍了。但说实话,光看书不练,等于白看。今天这一章,我就带你亲手把 ROS2 的开发环境搭起来,从工作空间到编译调试,走一遍完整的流程。
我个人习惯把 ROS2 的开发环境比作「厨房」——工作空间是你的料理台,包是你的食材,编译系统是炉灶,调试工具就是你的试吃勺。缺了哪样,这顿饭都做不香。
3.1 工作空间创建:你的第一个 colcon 工程
ROS2 的工作空间,说白了就是一个文件夹,里面按特定结构放你的代码。我刚开始用 ROS1 时用的是 catkin,后来切到 ROS2 的 colcon,说实话适应了好一阵子。但用顺手之后,你会发现 colcon 的设计更干净。
创建一个工作空间很简单,就这几步:
mkdir -p ~/autoware_ws/src
cd ~/autoware_ws
colcon build
嗯,这里要注意:src 目录放你的源码,build 和 install 目录是编译后自动生成的,别手贱去改它们。我曾经有个同事,非要去 build 目录里改编译中间文件,结果折腾了一下午没搞定,最后发现删掉重来最快。
colcon build --packages-select 你的包名 的习惯。全量编译在项目大了以后会慢到让你怀疑人生。
3.2 包管理:ROS2 的包到底长什么样?
一个 ROS2 包,本质上就是一个带有 package.xml 和 CMakeLists.txt(或 setup.py)的文件夹。你想想看,如果没有这两个文件,ROS2 根本不知道你这个文件夹是个啥。
创建一个新包,我推荐用命令:
cd ~/autoware_ws/src
ros2 pkg create my_first_pkg --build-type ament_cmake --dependencies rclcpp std_msgs
这条命令会帮你生成好骨架。你只需要往里面填代码就行。
这里有个坑,我踩过好几次:依赖声明。你在 package.xml 里写了依赖,但 CMakeLists.txt 里忘了加 find_package,编译时会报一些莫名其妙的错。说白了,两个文件要同步,缺一不可。
| 文件 | 作用 | 常见错误 |
|---|---|---|
| package.xml | 声明包的元信息和依赖 | 漏写依赖项 |
| CMakeLists.txt | 定义编译规则 | find_package 与 package.xml 不一致 |
3.3 编译系统:colcon 的进阶玩法
colcon 是 ROS2 的官方编译工具。说实话,它比 catkin 快了不少,尤其是增量编译这块。
我常用的几个编译命令:
colcon build—— 全量编译,第一次用这个colcon build --packages-select 包名—— 只编译某个包,省时间colcon build --symlink-install—— 符号链接模式,改 Python 文件不用重新编译
另外,编译完成后别忘了 source 环境:
source install/setup.bash
你可以把这行加到 ~/.bashrc 里,省得每次手动敲。
3.4 调试工具:rqt 与 ros2cli 实战
代码写完了,编译通过了,然后呢?你得跑起来看看对不对。ROS2 提供了一套非常强大的调试工具链。
3.4.1 ros2cli:命令行里的瑞士军刀
我个人最常用的是 ros2 topic echo 和 ros2 node info。举个例子:
ros2 topic echo /sensor/imu
这条命令能实时打印 IMU 数据。如果数据没出来,说明你的发布节点有问题,或者话题名字拼错了。别笑,我见过有人把 imu 拼成 immu,找了半小时 bug。
其他常用命令:
ros2 node list—— 查看所有活跃节点ros2 topic list—— 查看所有话题ros2 service list—— 查看所有服务ros2 param list—— 查看节点参数
3.4.2 rqt:图形化调试利器
如果你觉得命令行不够直观,那就上 rqt。启动方式很简单:
rqt
rqt 里我最常用的是 rqt_graph,它能画出节点和话题的关系图。你想想看,当你的系统有几十个节点时,光靠脑子记谁跟谁通信,根本记不住。一张图全搞定。
还有 rqt_plot,可以实时绘制数据曲线。调试 PID 控制器时,我全靠它看反馈值跟目标值的偏差。
3.5 本章知识体系总览
下面这张图,是我自己总结的 ROS2 开发流程。你可以把它贴在工位旁边,每次开发时对照着走一遍,基本不会漏步骤。
这张图把整个开发流程串起来了。你从左上角开始,一步步走到右下角,中间如果调试发现问题,就回到第三步修改代码。说白了,这就是一个迭代循环,直到所有模块都跑通为止。