搜“vmware上搭建Ubuntu 20.04 + ROS2”的人,大概分两类:一类是手头只有Windows笔记本、想低成本入门ROS的小白,另一类是公司电脑有各种管控、没法动系统分区,只能在虚拟机里折腾的老油条。我属于后者。如果你也想在这条路上少走弯路,这篇文章会把虚拟机配置、系统安装、ROS2换源、环境验证以及后面开发时遇到的坑,按我实际操作的过程完整讲一遍。很多细节不是教程封面会写的,但恰恰是决定你能否一次装成功的关键。
1. 为什么是VMware + Ubuntu 20.04 + ROS2 Foxy这套组合
1.1 虚拟机、双系统和WSL2:ROS2开发环境的三种选择
接触ROS2的第一件事不是敲命令,而是先想清楚环境怎么搭。目前主要就是三条路:直接装双系统、在VMware虚拟机里跑、用WSL2。这三条路我都在不同机器上试过,说点真实感受。
| 方案 | 优点 | 缺点 |
|---|---|---|
| 双系统 | 性能最好,图形、USB、网络全是真机级 | 要改分区,切换麻烦,引导坏了恢复成本高 |
| VMware虚拟机 | 配置灵活,快照随便折腾,对Windows依赖的用户友好 | 图形性能和GPU加速弱,外设需要透传 |
| WSL2 | 启动快,和Windows文件系统集成好 | DDS组播通信容易出问题,摄像头等硬件透传要看运气 |
双系统确实性能最强,但很多人完全离不开Windows环境,办公、网银、会议软件都在Windows上,每次重启切系统很影响节奏。WSL2看起来很美,实际用起来需要注意DDS发现机制跨网络拓扑的问题,尤其是你以后要做多机ROS2通信时,WSL2的NAT网络会让你排查到怀疑人生。况且WSL2里跑rviz2,虽然新版本支持WSLg图形界面,但渲染性能和稳定性偶尔会翻车。
VMware的好处在于:它提供一个完整的虚拟硬件环境,对Ubuntu的兼容性非常好,快照功能绝对是一大恩人——你在系统里乱装包、乱删系统文件,恢复一下一分钟搞定。这套方案是我在不同电脑上反复尝试后觉得最适合新手入坑的。
1.2 Ubuntu 20.04与ROS2 Foxy的版本配对逻辑
为什么偏偏是Ubuntu 20.04 + ROS2 Foxy?因为ROS2每个发行版都有明确绑定的Ubuntu版本,不能混用。ROS2 Foxy Fitzroy是2020年发布的支持到2023年的LTS版本,官方支持的是Ubuntu 20.04。如果选Ubuntu 22.04,对应的就是ROS2 Humble,虽然功能更新,但大量教程、答疑帖、开源代码仍然停留在Foxy时代。
我见过很多人在Ubuntu 22.04上按Foxy教程装,装到一半发现某个依赖包不存在,或者某个消息类型名称对不上,最终卡死。对新手来说,选一个教程覆盖密度最高的组合,比选一个最前沿的版本要省心得多。而且20.04这个系统本身非常稳定,配套的OpenCV、Python 3.8、Qt版本都经过长期验证,跑ROS2桌面版很舒服。你如果确定以后要长期用新版本,直接选22.04+Humble也可以,但那就别按这篇文章的版本号来操作了。
2. VMware里安装Ubuntu 20.04的关键设置:这些选项先别乱动
2.1 新建虚拟机时的硬件与显卡配置
我在VMware Workstation里新建虚拟机时选择“典型”,镜像指到ubuntu-20.04.6-desktop-amd64.iso。内存这块我建议至少分配4GB,如果后面准备用colcon编译自己的ROS2包,4GB是及格线,主机内存余量够的话给到6GB或者8GB会更舒服。CPU分配至少2核心4线程,编译的时候多核优势非常明显。磁盘容量建议60GB起步,只学基础命令40GB勉强够,但后面包和编译缓存一多,磁盘满了再扩容反而麻烦。
这里有一个我踩过的大坑:在“显示器设置”里一定要勾选“加速3D图形”。这一步直接影响后面rviz2能不能正常渲染。VMware的3D加速是虚拟OpenGL,虽然性能不强,但跑rviz2的机器人模型和turtlesim完全够。我当时第一次装没勾这个选项,后面打开rviz2直接黑屏,反复排查Driver问题,最后才发现是虚拟机选项没开。说实话,这个选项在安装流程中特别容易被忽略。
2.2 镜像选择与安装过程中的建议
镜像文件要去Ubuntu官网下载,注意选20.04.6这类最新小版本,别用早期20.04.1。因为老版本已经停止维护,默认软件源全部指向旧地址,apt update会报404。安装语言我建议选英文,中文可以在系统里后装输入法。原因很现实:ROS2开发中你几乎每天都要看终端报错,英文报错关键词直接搜索就能命中别人踩坑的解决方案,而中文locale有时候会把错误信息翻译得面目全非,搜都搜不到。
分区上虚拟机完全不需要手动折腾,直接用“清除整个磁盘并安装Ubuntu”就可以。安装时保持网络连接,让安装器正常下载更新。装完重启后第一件事是进系统设置看看软件更新器,确认系统已经更新到最新状态,然后再开始后续配置。
2.3 装完系统先做这三件事:Tools、中文输入法与软件源
第一件事是装VMware Tools。新版VMware Workstation已经用open-vm-tools替代了老式tools,Ubuntu桌面版默认带了一部分,但不一定完整。为了确保共享文件夹、剪贴板互通、分辨率自适应全部可用,执行:
sudo apt update sudo apt install open-vm-tools open-vm-tools-desktop装完重启虚拟机,鼠标移出窗口不再卡住,主机的屏幕分辨率也能自动适配VMware窗口。第二件事是中文输入法,在系统设置的Region & Language里添加IBus拼音即可,不需要额外装fcitx框架。第三件事是把Ubuntu软件源换成国内镜像站,这个虽然不直接影响ROS2安装,但后续apt安装依赖的速度会差出十倍。
3. ROS2 Foxy安装全流程:换源、依赖和那个反复出现的key错误
3.1 先换Ubuntu软件源再装ROS2
ROS2的安装会拉取大量系统依赖库,比如python3、cmake、libboost、nasm等,所以先把/etc/apt/sources.list里的Ubuntu源换掉是必须的。Ubuntu 20.04的源文件路径就是/etc/apt/sources.list,默认指向archive.ubuntu.com和security.ubuntu.com,访问速度不稳定。换成阿里云或者清华镜像源后,执行sudo apt update的速度会明显改善。
除了系统源,pip源也要顺手换掉。ROS2的Python工具链colcon、rosdep、vcstool等等很多通过pip安装,pip源卡住的时候整个安装过程都会卡住,而且报错信息特别难判断。解决方法是修改或创建~/.pip/pip.conf,把index-url指向国内的PyPI镜像源。这一步做完,后续安装会顺畅非常多,属于典型的“前期两分钟,后期省两个小时”的投入。
3.2 添加ROS2源时最折磨人的一步
ROS2官方安装教程要求把packages.ros.org的apt源添加进系统。最让人抓狂的是,在部分网络环境下这个源访问极慢,甚至连接失败。国内镜像站已经做好了ROS2源的镜像,路径是在镜像站域名下的ros2/ubuntu。所以可以直接用国内镜像源替代官方源:
sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update && 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=amd64,arm64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu focal main" | sudo tee /etc/apt/sources.list.d/ros2.list这里最典型的坑就是这个gpg key文件的下载。raw.githubusercontent.com经常连接超时或者返回不完整的文件,我遇到过curl显示下载成功,但文件只有几十个字节的情况。这种问题在apt update的时候才会暴露,报一个NO_PUBKEY,你顺着提示去keyserver拉公钥,又会卡在keyserver连接上。我的建议是,下载完key文件后马上用ls -l查看字节数,正常情况这个key文件有几KB,如果只有几十字节,删掉重新下载,或者从镜像站提供的key地址下载。
3.3 安装ROS2本体:Desktop版还是Base版
源配置好之后,安装命令非常简单:
sudo apt update sudo apt install ros-foxy-desktopinstall的时候注意区分Desktop和Base两种包。Desktop版包含rviz2、turtlesim、demo节点、graphviz这些可视化工具,适合在虚拟机上学习开发;Base版只保留核心通信库和命令行工具,适合部署到嵌入式设备。如果你是在虚拟机里学ROS2,建议直接上Desktop版,省得之后缺一个包补一个包,补包的过程有时候比装系统还烦。
装完ROS2之后,需要在~/.bashrc里加上一行,让每次打开终端都能自动加载ROS2环境:
echo "source /opt/ros/foxy/setup.bash" >> ~/.bashrc source ~/.bashrc然后执行ros2 --help验证一下。如果输出了一大段帮助信息,说明环境已经生效。此时再补两个开发必备工具:
sudo apt install python3-colcon-common-extensions python3-rosdepcolcon是ROS2的编译工具集,后面创建自己的工作空间时要经常用。rosdep可以用来解决源码包的依赖问题,虽然新手阶段用得少,但提前装好总没错。如果rosdep init因为网络问题卡住,可以先跳过这一环节,等真的要编译第三方源码包时再处理。
4. 验证ROS2环境:从talker/listener到rviz2和小乌龟
4.1 终端通信测试:确认核心功能正常
装完环境后第一件事,就是用官方自带的demo节点验证通信链路。开两个终端,第一个终端运行:
ros2 run demo_nodes_cpp talker第二个终端运行:
ros2 run demo_nodes_cpp listener如果终端A不断输出“Publishing: 'Hello World'”,终端B能同步收到,说明ROS2最核心的发布订阅机制已经跑通。这个测试看起来很简单,但它验证的是多进程通过DDS通信这条完整链路在虚拟机环境下是否正常。这一步如果出问题,后面所有关于消息、服务、动作的练习都会跟着卡壳。在默认NAT网络模式下,VMware虚拟机内部的节点间通信一般是没问题的,如果你发现两个节点互相发现不了,先检查系统防火墙有没有放行组播流量。
4.2 图形界面工具:rviz2与turtlesim
命令行通信通了之后,接着验证图形界面。先试rviz2:
ros2 run rviz2 rviz2正常情况下会弹出RViz主窗口,有3D视图和显示面板。如果窗口能出来但是全黑,或者终端里报OpenGL context相关的错误,八成就是开头说的“加速3D图形”没勾上。关掉虚拟机电源后在虚拟机设置里勾选该选项,重启再试。如果已经勾选但还是有问题,可以执行glxinfo | grep renderer看渲染器的名字,如果显示llvmpipe说明走的是软件渲染,性能比较差但至少能用。
小乌龟Turtlesim是另一个很适合验证图形环境的工具。先运行:
ros2 run turtlesim turtlesim_node会弹出一个蓝色窗口,里面出现一只小海龟。再开一个终端运行:
ros2 run turtlesim turtle_teleop_key然后用方向键控制海龟移动。这个过程能直观理解“节点—话题—消息”这三个核心抽象,比盯着命令行兴奋多了。我一般都会推荐刚上手的人把海龟跑一遍,它比talker/listener更容易建立直觉。
4.3 用colcon创建自己的第一个工作空间
跑通官方示例后,真正的开发是从自己的工作空间开始的。创建并进入src目录:
mkdir -p ~/dev_ws/src cd ~/dev_ws/src ros2 pkg create --build-type ament_cmake my_robot_bringup然后回到dev_ws根目录执行:
cd ~/dev_ws colcon build如果你在编译过程中发现内存不够或者内存交换导致的卡顿,可以添加上限标志来限制并行任务数:
colcon build --executor sequentialcolcon build完成后,dev_ws目录下会生成build、install、log三个目录。使用时记得source安装脚本:
source ~/dev_ws/install/setup.bash然后你就能在ros2 pkg list里看到自己创建的包。组件新手容易忽略的一个点:每次新开终端只source了/opt/ros/foxy/setup.bash,自己的工作空间install目录还需要手动source一次。如果嫌麻烦,可以把这一行也写进.bashrc,但是后期工作空间多了会比较乱,我自己习惯是每开一个终端手动source一次,形成肌肉记忆。
5. 虚拟机下ROS2开发的硬骨头:共享目录、GUI加速、设备访问与多机通信
5.1 共享文件夹的权限坑
宿主机Windows和虚拟机Ubuntu之间交换文件,最常用的是VMware共享文件夹。设置好共享路径后,虚拟机里的/mnt/hgfs目录下会出现宿主机文件夹。但你很可能遇到“能看到目录却没有写权限”的情况,原因是共享文件夹挂载的属主是root,普通用户没有写权限。网上很多旧教程让修改/etc/fstab加挂载参数,我实测在open-vm-tools下更省事的方法是用当前用户ID重新挂载:
sudo mount -t vmhgfs .host:/共享文件夹名 /mnt/hgfs/共享文件夹名 -o uid=$(id -u),gid=$(id -g)还有一个重要提醒:别在共享文件夹里直接跑colcon build。Windows文件系统不支持符号链接,ROS2安装目录和构建缓存里大量使用符号链接,放在跨文件系统上会导致各种奇怪问题。我见过有人在这里折腾一下午,最后发现是共享目录的问题。正确的姿势是:源码放在虚拟机本地目录,构建也在本地,共享文件夹只用来中转压缩包和最终产物。
5.2 rviz2渲染崩溃的排查路径
rviz2在虚拟机里图形异常是最常见的问题。现象包括:窗口黑屏、显示不全、拖拽模型时画面闪烁甚至崩溃。排查顺序我个人建议如下:
- 确认VMware显示设置里的3D加速已经勾选。
- 在虚拟机里执行glxinfo | grep renderer组合,确认OpenGL渲染器是否正常加载。
- 如果渲染器显示的是llvmpipe或者软渲染,说明硬件加速没有生效,先尝试重装open-vm-tools-desktop。
- 如果rviz2还是闪退,可以试试强制软件渲染模式启动rviz2:
LIBGL_ALWAYS_SOFTWARE=1 ros2 run rviz2 rviz2这个兜底方案牺牲一些性能和流畅度,但能让rviz2稳定跑起来。对学习阶段来说,能用比流畅重要。
5.3 DDS组播与虚拟机的网络模式
ROS2的节点发现默认依赖DDS组播,这个话题值得单独拎出来讲。VMware的NAT模式下,虚拟机由虚拟网卡连接到宿主机内部的虚拟交换机,组播通信被限制在虚拟网段内。这种情况下,虚拟机内部的多个ROS2节点之间通信没问题,但如果你想让宿主机上的节点或者局域网里其他电脑上的节点跟虚拟机里的节点通信,就需要把虚拟机网络模式改成桥接模式。
修改网络模式的方法很简单:关机后在虚拟机设置里把网络连接从NAT改为桥接。改完后虚拟机会直接从路由器获取IP,和宿主机处于同一个二层网络。如果桥接后还是发现不了对方,用以下命令排查:
ros2 multicast receiveros2 multicast send在两个终端分别执行接收和发送,确认组播通不通。如果不通,再检查双方的防火墙规则。这个排查路径适用所有ROS2多机通信问题,比乱猜靠谱得多。
5.4 摄像头与USB设备访问
做机器人开发迟早要接摄像头、雷达或者开发板到虚拟机里。VMware对本机USB设备的透传做得不错,但有个常见误区:你不是插上就能用,需要在VMware菜单的“虚拟机—可移动设备”里把对应的设备连接进虚拟机。这一步本质上等于把物理USB设备从宿主机“断开”,重新挂接到虚拟机内部。
关于USB控制器版本,在虚拟机设置里的USB控制器选项建议选择USB 3.1兼容,否则某些高速设备只能降级到USB 2.0速率,能用但数据传输非常慢。摄像头接入虚拟机后确认一下设备节点是否存在:
ls /dev/video*如果能看到video0,usb_cam节点就能正常工作。要注意的是,宿主机如果开着摄像头软件,设备会被占用,虚拟机这边是无法同时拿到的。这个问题不是VMware的Bug,是USB设备的独占特性。
虚拟机环境下做ROS2开发,另一个很多人问的坑是时间同步。VMware Tools默认会把宿主机时间同步到虚拟机,但如果你在多机通信时发现节点时间戳不一致,先检查宿主机本身有没有开启自动时间同步。这个细节容易漏,但赶不上前面那几个坑的折腾程度,我放在这里是为了提醒你,做多机实验前一定先ntpdate或者配好chrony,时间不同步会导致TF变换和日志数据全是乱的。
整套环境搭下来,我最大的感受是:搭环境的困难不在命令本身,而在“版本的对应关系”和“网络与硬件的边界条件”。很多人按教程一步不差地敲命令,最后还是失败,往往是因为Ubuntu小版本选错、3D加速没勾、DDS组播被NAT挡住这类教程不写但非常关键的前提条件。希望这篇记录能把VMware上搭建Ubuntu 20.04 + ROS2的这些隐藏条件一次说透,让你至少能在半天内跑起来一个能干活的环境。