2. 开发环境搭建:Ubuntu系统配置、ROS2 Humble安装、交叉编译工具链配置

说实话,嵌入式ROS开发最让人头疼的往往不是算法本身,而是环境搭建。我见过太多新手卡在这一步,一卡就是好几天。今天我就把这几年的经验捋一捋,带你把这套环境搭得明明白白。

2.1 Ubuntu系统配置——打好地基

我个人习惯用Ubuntu 22.04 LTS,原因很简单:ROS2 Humble官方推荐的就是这个版本。你想想看,官方测试最多的系统,坑自然最少。

系统要求速查表

项目推荐配置最低要求
操作系统Ubuntu 22.04 LTSUbuntu 20.04
内存16GB8GB
磁盘空间80GB40GB
CPU4核以上双核

装完系统后,第一件事就是换源。别问我为什么,你试试不换源装个ROS2,等半小时还在转圈,你就懂了。

# 备份原源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 替换为清华源(我个人最常用)
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

# 更新
sudo apt update && sudo apt upgrade -y

小技巧:我习惯装完系统先装这几个包——vim、git、curl、net-tools。别小看它们,后面调试的时候能省不少事。

2.2 ROS2 Humble安装——别踩这些坑

ROS2 Humble是2022年5月发布的,到现在已经很稳定了。我在项目里用了大半年,基本没出过什么幺蛾子。

安装过程其实就三步,但每一步都有坑。我一个个说。

2.2.1 设置语言环境

这一步很多人会跳过,结果后面编译时一堆乱码错误。嗯,这里要注意:

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

2.2.2 添加ROS2源

记得先装curl和gnupg,不然会报错。我曾经在这卡了半小时,后来发现是没装gnupg。

sudo apt install curl gnupg lsb-release
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

2.2.3 安装ROS2 Humble

这里有两个选择:桌面版和基础版。我建议你装桌面版,因为包含了可视化工具,调试时很有用。

# 桌面版(推荐)
sudo apt install ros-humble-desktop

# 或者基础版(仅命令行)
# sudo apt install ros-humble-ros-base

注意:安装过程可能会提示你安装一些依赖包,比如python3-colcon-common-extensions。别犹豫,直接装。我见过有人跳过依赖,结果编译工作空间时报错,又回头补装。

2.2.4 配置环境变量

装完别忘了配置环境变量。我习惯把它写到.bashrc里,这样每次打开终端自动生效。

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

验证一下是否安装成功:

ros2 run demo_nodes_cpp talker

如果看到"Hello World"在刷屏,恭喜你,装好了。

2.3 交叉编译工具链配置——嵌入式开发的核心

交叉编译,说白了就是在PC上编译出能在ARM板子上跑的程序。我刚开始做嵌入式ROS时,总觉得直接在板子上编译不就行了?后来发现,板子那点算力,编译一个功能包能等半小时。嗯,从那以后我再也不敢偷懒了。

2.3.1 安装交叉编译工具链

以ARM Cortex-A系列为例,我常用的是gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf。为什么选这个?因为我在项目里实测过,兼容性最好。

# 下载工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz

# 解压到指定目录
sudo tar -xf gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz -C /opt/

# 配置环境变量
echo 'export PATH=$PATH:/opt/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc

# 验证
arm-none-linux-gnueabihf-gcc --version

2.3.2 配置ROS2交叉编译环境

这里有个关键点:ROS2的交叉编译需要用到toolchain文件。说白了就是告诉编译器:目标平台是什么、头文件在哪、库文件在哪。

我写了一个通用的toolchain文件,你可以直接拿来用:

# 创建toolchain文件
cat > ~/ros2_ws/toolchain.cmake << 'EOF'
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# 指定交叉编译器
set(CMAKE_C_COMPILER /opt/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER /opt/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-g++)

# 指定sysroot(目标系统的根文件系统)
set(CMAKE_SYSROOT /opt/ros2_humble_sysroot)

# 查找工具链中的程序
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOF

关键点:CMAKE_SYSROOT指向的是目标板子的根文件系统。你需要把板子上的/usr、/opt等目录拷贝到PC上,或者用QEMU模拟。我一般用rsync同步:

rsync -avz root@板子IP:/ /opt/ros2_humble_sysroot/

2.3.3 编译测试

配置好之后,就可以交叉编译ROS2功能包了。我习惯用colcon,加上--cmake-args参数指定toolchain文件:

cd ~/ros2_ws
colcon build \
  --cmake-args \
  -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
  -DCMAKE_BUILD_TYPE=Release

避坑指南:我曾经在编译时遇到"找不到rosidl_typesupport"的错误。后来发现是sysroot里缺少ROS2的安装文件。解决办法:在板子上完整安装一遍ROS2 Humble,然后再同步sysroot。

2.4 验证环境——跑个例子试试

环境搭好了,总得验证一下。我一般写个简单的发布订阅程序,在PC上编译,然后拷到板子上跑。

# PC端交叉编译
cd ~/ros2_ws
colcon build --packages-select my_test_pkg --cmake-args -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake

# 把编译好的文件拷到板子上
scp install/my_test_pkg/lib/libmy_test_pkg.so root@板子IP:/opt/ros2_humble/lib/

# 板子上运行
ssh root@板子IP
source /opt/ros/humble/setup.bash
ros2 run my_test_pkg my_test_node

如果能看到节点正常运行,说明你的环境搭建成功了。

最后提醒一句:交叉编译时,一定要注意目标板子的架构。ARMv7和ARMv8的指令集不同,编译选项也不一样。我见过有人用ARMv7的工具链去编译ARMv8的程序,结果跑起来直接段错误。

好了,环境搭建这部分就到这里。下一章我们聊聊ROS2的节点通信机制,那才是真正有意思的东西。