3、搭建ROS2开发环境:在Ubuntu 22.04上安装ROS2 Humble,配置工作空间并编译第一个包

好,咱们正式开始动手了。这一章的目标很明确——在你的Ubuntu 22.04上把ROS2 Humble装好,然后建个工作空间,编译一个自己的包。听起来简单,但这里面的坑其实不少。我当年第一次装ROS2的时候,光环境变量就折腾了半小时。嗯,咱们一步步来。

3.1 为什么选Ubuntu 22.04 + ROS2 Humble?

你可能要问,为什么非得是Ubuntu 22.04?ROS2版本那么多,为什么偏偏选Humble?

说白了,这是官方推荐的长期支持组合。Ubuntu 22.04是LTS版本,稳定到2027年。ROS2 Humble也是LTS版本,支持到2027年。你想想看,做机器人项目最怕什么?最怕系统突然不维护了,或者依赖包冲突到崩溃。我在项目中遇到过好几次,因为用了非LTS版本,半年后被迫迁移整个开发环境,那叫一个痛苦。

所以我的建议是:生产环境老老实实用LTS。Humble对应Ubuntu 22.04,就像Galactic对应Ubuntu 20.04一样,都是官方钦定的组合。别乱搭,否则你会被依赖问题折磨到怀疑人生。

3.2 安装ROS2 Humble

安装过程其实不复杂,但有几个关键步骤容易出错。我直接给你最稳的安装方式。

3.2.1 设置语言环境和源

先确保你的系统语言环境是UTF-8。这一步很多人会跳过,但后面编译某些包时会报奇怪的编码错误。

sudo apt update
sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

然后添加ROS2的软件源。注意,这里要用官方源,别用第三方源,否则版本对不上。

sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update
sudo apt install curl
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update
小提示: 如果你在国内,网络可能比较慢。我建议你换成国内镜像源,比如清华或中科大的。具体方法网上搜一下就有,但记得只换ROS2的源,别把整个系统的源都换了,否则容易出兼容性问题。

3.2.2 安装ROS2 Humble桌面版

我个人习惯装桌面版,因为包含了RViz、Gazebo这些可视化工具,调试起来方便。如果你是在服务器上部署,可以只装基础版。

sudo apt install ros-humble-desktop

这个命令会下载大概1.5GB的东西,耐心等。我记得第一次装的时候,网速慢,等了快一个小时。你可以趁这个时间喝杯咖啡,或者看看文档。

3.2.3 设置环境变量

安装完只是第一步。你得让系统知道ROS2在哪。每次打开终端都要执行这个命令:

source /opt/ros/humble/setup.bash

但每次都手动敲太烦了。我建议你把它加到 ~/.bashrc 里:

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc
注意: 如果你同时装了ROS1和ROS2,千万别把两个source都写进bashrc。否则环境变量会打架,你调用ros2命令时可能莫名其妙跑到ROS1的路径下。我曾经因为这个排查了整整一下午。

3.3 验证安装是否成功

装完了,怎么知道好不好使?最简单的办法,跑两个终端测试一下。

终端1:启动一个发布者节点

ros2 run demo_nodes_cpp talker

终端2:启动一个订阅者节点

ros2 run demo_nodes_py listener

如果你看到终端1不断输出 Publishing: 'Hello World',终端2不断输出 I heard: 'Hello World',那就说明ROS2安装成功了。嗯,就是这么简单。

3.4 创建工作空间

工作空间是ROS2开发的基本单位。说白了,就是一个文件夹,里面放着你的代码、依赖和编译产物。ROS2用的是colcon编译工具,不是ROS1的catkin了,这个要记住。

3.4.1 创建并初始化工作空间

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build

第一次执行 colcon build 时,它会自动创建 buildinstalllog 这三个文件夹。你不需要手动创建它们。

重要: 每次编译完,都要source一下install目录下的setup.bash,否则你新编译的包找不到。
source ~/ros2_ws/install/setup.bash
同样,建议把这个也加到bashrc里,但要注意顺序——先source ROS2的,再source你工作空间的。

3.5 编译第一个包

好,现在我们来创建一个最简单的包。这个包只做一件事:打印一条日志。

3.5.1 创建包

cd ~/ros2_ws/src
ros2 pkg create my_first_pkg --build-type ament_cmake --dependencies rclcpp

这个命令会生成一个名为 my_first_pkg 的包,使用CMake作为构建系统,依赖 rclcpp(ROS2的C++客户端库)。

生成的目录结构是这样的:

my_first_pkg/
├── CMakeLists.txt
├── include/
│   └── my_first_pkg/
├── package.xml
└── src/

3.5.2 写一个简单的节点

src/ 目录下创建一个 my_first_node.cpp 文件:

#include "rclcpp/rclcpp.hpp"

int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<rclcpp::Node>("my_first_node");
    RCLCPP_INFO(node->get_logger(), "Hello, ROS2! 我的第一个节点跑起来了。");
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

这段代码很简单:初始化ROS2,创建一个节点,打印一条日志,然后进入事件循环。

3.5.3 修改CMakeLists.txt

打开 CMakeLists.txt,在文件末尾添加:

add_executable(my_first_node src/my_first_node.cpp)
ament_target_dependencies(my_first_node rclcpp)

install(TARGETS
    my_first_node
    DESTINATION lib/${PROJECT_NAME}
)

这里要注意,install 那一段不能少。否则编译出来的可执行文件不会安装到install目录,你运行时会找不到。

3.5.4 编译并运行

cd ~/ros2_ws
colcon build --packages-select my_first_pkg
source install/setup.bash
ros2 run my_first_pkg my_first_node

如果一切顺利,你会看到终端输出:

[INFO] [my_first_node]: Hello, ROS2! 我的第一个节点跑起来了。
小技巧: 使用 --packages-select 可以只编译指定的包,不用每次都编译整个工作空间。我开发时经常只改一个包,用这个参数能省不少时间。

3.6 避坑指南

最后,分享几个我踩过的坑:

  • Python包和C++包不要混在一个目录下——colcon有时候会搞混,建议分开建子目录。
  • 不要用sudo编译——我见过有人用 sudo colcon build,结果编译出来的文件权限全乱了,普通用户没法source。
  • 如果编译报错说找不到某个依赖——先检查 package.xml 里有没有声明,再检查系统里有没有安装对应的库。用 rosdep install 可以自动安装依赖。

嗯,到这里,你的ROS2开发环境就搭好了。下一章我们会真正开始写一个有点意思的节点,让它能订阅和发布消息。准备好了吗?