1. 为什么无人机开发绕不开 Ubuntu 20.04
1.1 开源飞控生态的现实:你在和什么打交道
做无人机软件开发,特别是接触开源自驾仪(PX4、ArduPilot)或者相关的机载计算机、视觉导航、ROS 集群这类方向,Linux 基本不是“选项”,而是“默认前提”。Windows 当然能装地面站、能看日志,但一旦涉及源码编译、设备驱动、仿真环境、通信协议栈,几乎所有上游工具链都优先面向 Linux 提供支持和测试。你可以用虚拟机凑合,但真正的工程环境,大家默认就是 Ubuntu。
那为什么偏偏是 Ubuntu 20.04?因为它对应的是 ROS Noetic 和 ROS2 Foxy 这两个长期发行版的核心阵地,而 PX4 官方文档长期以 Ubuntu 20.04 作为推荐系统,QGroundControl、MAVSDK、Gazebo 仿真这些配套工具的安装脚本、依赖测试、已知问题列表,全都围绕 20.04 展开。这不是说 20.04 比其他版本“更先进”,而是整个生态在你之前已经把坑踩完了。对开发者来说,稳定的生态比新系统带来的那点性能提升重要得多。
1.2 版本选择的讲究:为什么是 20.04 而不是 22.04 或 24.04
这里要说清楚一个概念:Ubuntu 20.04 是 2020 年 4 月发布的长期支持版本(LTS),官方支持到 2025 年,代号 Focal Fossa。LTS 的意思就是五年维护周期内持续推送安全更新和补丁,而不是像普通版本那样半年就失去支持。对于需要长期迭代、跨学期/跨项目复用的无人机开发环境来说,LTS 是唯一的理性选择。
为什么不是 22.04 或者更新的 24.04?我个人的体会是——无人机软件环境里有大量依赖是“慢半拍”的。你用的飞控固件、机载 SDK、视觉库,很多二进制包或者源码编译指南都基于 20.04 验证过,到了 22.04 上,OpenCV 版本、Python 版本、系统库路径都可能出现细微差异,表面上看着能装,但编译到一半报一个莫名奇妙的底层库错误,排查起来非常痛苦。还有,Ubuntu 22.04 默认 Python 3.10,而很多无人机相关的自动化脚本和数据工具链,在 Python 3.8(20.04 默认)下跑得最稳。
另外,从“工程复现”的角度看,统一版本本身就是一种团队协作策略。别人把环境配好跑通了,你和他在同一个系统版本、同一套依赖下,理论上结果一致。这在课程项目、竞赛团队、课题组里价值极大。你不需要理解为什么,只需要知道:用 20.04,遇到的坑最少,能搜到的解决方案最多。这就赢了。
2. 搭建环境的四条路线,怎么选才对
2.1 双系统:性能党和目标机模拟的最佳选择
如果你需要跑 Gazebo 仿真、PX4 SITL(Software In The Loop),或者打算在机载电脑上部署代码,双系统是首选。它的优势很直接:硬件资源全部归 Linux 用,不用经过虚拟化层。编译固件时 CPU 能跑满,仿真渲染也不卡顿。
分区建议:/boot给 1GB,/给 50GB 以上(装 ROS、PX4 工具链、依赖库非常占空间),/home单独划出来,越大越好,你的源码、数据集、日志都放这里。Swap 建议给到 8GB 左右,编译大型工程时内存溢出可以兜底。
初装双系统最容易踩的坑有三个。一是 Windows 快速启动没关,导致 Ubuntu 安装完重启后直接进 Windows,或者磁盘分区表异常;解决方法是在 Windows 电源选项里禁用“快速启动”。二是无线网卡识别不了,Ubuntu 20.04 对部分 Realtek 网卡支持不佳,需要手动装驱动,建议安装前先查一下你网卡型号的兼容性。三是安装时选择“与 Windows 共存”经常出问题,我推荐手动分区,自己分配挂载点,虽然麻烦一点但心里有数。
2.2 虚拟机:快速上手但别想跑重活
对于刚接触 Linux 的同学,或者只在 Windows 上办公、偶尔需要 Linux 环境的场景,虚拟机是最低成本的入口。VMware Workstation 或者 VirtualBox 都可以。你不需要重新分区,不用承担装坏系统的风险,几分钟就能启动一个 Ubuntu 实例。
但虚拟机有两个硬伤。第一是 3D 加速问题,Gazebo 仿真里加载复杂世界模型时,帧率低到没法用,你以为是代码问题,其实是虚拟显卡的性能瓶颈。第二是 USB 设备直通不稳定,连接 Pixhawk 等飞控硬件时,虚拟机经常出现掉线、串口识别不到的问题。所以我的建议是:虚拟机只用来学命令、写基础 ROS 节点、看文档和环境验证,真刀真枪的仿真和硬件调试,老老实实回双系统。
另外说一个细节:虚拟机磁盘不要用默认的“动态分配”,因为动态分配的虚拟磁盘文件会不断膨胀,而且一旦宿主机磁盘碎片化,IO 性能会明显下降。直接固定大小,比如 60GB,省心。
2.3 WSL2 与 Docker:另一种可行的轻量方案
WSL2 在 Windows 上提供了一个接近原生 Linux 的内核环境,启动速度快,能跑大多数命令行工具。对于只想用 Linux 终端、写点脚本、编译小工程的场景,WSL2 够用。而且 WSL2 支持你不需要单独装虚拟机软件,微软商店里直接安装 Ubuntu 20.04 就行。
但 WSL2 做无人机开发有两个明显的限制:一是 GUI 应用支持虽然在改进,但跑 Gazebo、QGroundControl 这类需要图形界面的工具,体验一般;二是 USB 串口直通需要额外配置 usbipd,操作繁琐,而且版本更新后经常出兼容问题。如果你只做算法仿真、数据后处理,WSL2 是个不错的选择;如果你要接飞控真机,建议放弃这条路。
Docker 则是另一套思路:把环境打包成镜像,分发到任何机器上都能一键复现。这在团队协作里非常香,比如你配好了一套 PX4 编译环境,推给队友,他拉下来直接用,不再需要在自己的机器上一步步踩坑。但 Docker 不适合需要图形界面和大量硬件直通的场景,一般配合 VNC 或者 Web 界面使用,属于进阶玩法,新手阶段先不碰。
2.4 我的建议:真实的选型逻辑
如果你还在犹豫,我给你的决策路径是:
- 没接触过 Linux,只想先看看:虚拟机装 Ubuntu 20.04,玩两周再说。
- 确定要做飞控开发、要跑仿真、以后要接真机:直接双系统,一步到位。
- 以 Windows 为主,偶尔用 Linux 做数据分析/脚本处理:WSL2。
- 团队要统一环境,反复交付部署:配 Docker 镜像。
这个顺序基本覆盖了从入门到工程的完整跨度。记住,选环境的核心不是“哪个最酷”,而是“哪个能让我少浪费时间在环境问题上,把精力留给代码和算法”。
3. Linux 工程基础:不是背命令,是建立工程思维
3.1 你真正高频用到的命令(按场景分类)
很多新手学 Linux 是打开一篇“常用命令大全”,然后从ls背到tar,背完就忘。我的建议完全不同——不要按命令清单学,按你的实际场景学。无人机开发中,你高频遇到的场景就是:操作文件、查日志、装软件、改权限、看进程、配网络。
文件操作:ls -lh(看文件大小和权限)、cd、cp -r、mv、rm -rf(慎用)、find /path -name "*.txt"(按文件名查找)、grep -r "关键字" /path(在文件内容里搜关键字)。
日志查看:tail -f(实时跟踪日志输出)、journalctl -u 服务名(查系统服务日志)、dmesg | grep -i error(查内核报错,插拔 USB 设备时看这个最有用)。
权限与用户:sudo、chmod +x(加执行权限)、chown 用户名:组名 文件(改文件归属)、id(查当前用户信息)。
软件管理:apt update、apt install 包名、apt remove 包名、dpkg -l | grep 包名(查已装包)。
进程与网络:ps aux | grep 进程名(查进程)、kill -9 PID(强杀进程)、netstat -tunlp(查端口占用)、ip addr(看 IP)。
这些命令单独的语法都很简单,真正的难点在于组合使用。比如排查飞控连接问题,你要先ls /dev/ttyUSB*看设备有没有生成,再dmesg | tail看内核认不认,再sudo chmod 777 /dev/ttyUSB0修权限,然后才能让 QGC 连上。这个链条里每一步都是“看到现象,定位原因,做出动作”,而不是单纯背诵某个命令。
3.2 用户与权限:为什么你的设备老是 permission denied
无人机开发里报permission denied最多的地方,不是文件,而是设备节点。你插入 Pixhawk 飞控,系统生成了/dev/ttyUSB0,但当前用户不在dialout用户组里,所以没权限访问。解决办法有两种:
临时方案:每次插上设备后执行sudo chmod 666 /dev/ttyUSB0,但设备重新插拔后权限会重置,只适合应急。
永久方案:把当前用户加入dialout组,执行sudo usermod -a -G dialout $USER,然后注销重新登录。这样系统默认允许该用户访问串口设备,一步到位。
另外一个更专业的做法是写 udev 规则。比如为特定飞控设备固定设备名并自动设置权限,在/etc/udev/rules.d/下新建一个规则文件,内容大概是:
SUBSYSTEM=="tty", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", MODE="0666", SYMLINK+="flight_controller"这样插上设备后,/dev/flight_controller就会自动出现,而且无需手动授权。其中idVendor和idProduct可以通过lsusb命令查到。这个操作在开发板上接各种传感器时经常用到,属于工程基础中的基础,值得花时间彻底搞懂。
3.3 软件包管理与环境变量
Ubuntu 的软件安装核心是apt,它从软件源拉取软件包并自动处理依赖关系。新手经常遇到的一个问题是:默认软件源在国外,下载速度很慢。解决办法是把/etc/apt/sources.list里的源地址替换为国内镜像源,比如清华、阿里云、中科大。改完以后执行sudo apt update刷新索引,再装软件就快多了。
环境变量是另一个绕不过去的概念。你安装完 CUDA 以后,需要把它的bin目录加到PATH,把lib目录加到LD_LIBRARY_PATH,否则命令行找不到nvcc,程序运行时也找不到动态库。这些一般都写在~/.bashrc文件末尾,比如:
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH改完以后执行source ~/.bashrc生效。这里有个容易犯的错:路径写错或者顺序搞反,导致系统命令都找不到。改环境变量之前最好备份一下~/.bashrc,一旦出问题可以恢复。
4. 从零搭建一套可用的无人机开发环境
4.1 系统安装后的第一件小事:换源与更新
系统装完,第一件事不是装 ROS,而是换软件源。因为后面所有工具链都要通过apt安装,源的速度直接决定你的等待时间。我一般用清华源,把/etc/apt/sources.list里archive.ubuntu.com相关的地址替换成mirrors.tuna.tsinghua.edu.cn,然后执行:
sudo apt update sudo apt upgrade -y更新完以后装基础开发工具包,一次性把编译链和版本管理工具装好:
sudo apt install -y build-essential git cmake curl wget vim其中build-essential包含 gcc/g++ 和 make,是编译一切的根基;git用于拉取源码;cmake是 PX4、OpenCV 等大型项目使用的构建系统。这一步完成后,系统才具备了“安装其他东西”的基本能力。
这里我特别想提醒一点:Ubuntu 系统更新时经常会提示“是否升级到新版内核”,对无人机开发环境来说,除非有明确需求,否则不建议频繁升级内核。新版内核可能会破坏 NVIDIA 驱动和部分硬件驱动,导致重启后进不了图形界面。我自己的习惯是设置软件更新器,把“自动检查更新”关掉,手动选择有把握的安全更新。
4.2 NVIDIA 驱动与 CUDA:要不要装,怎么装
先说结论:如果你只是编译飞控固件、跑 ROS 基础节点、用 QGC 地面站,NVIDIA 驱动和 CUDA 都不是必需的。这些软件的渲染和计算都依赖 CPU 和默认图形驱动就能完成。但如果你要做机载视觉、目标检测、深度学习模型部署,那显卡驱动和 CUDA 就是刚需。
我遇到过不少同学一上来就装 CUDA,结果把系统搞崩了,其实他的项目根本用不到 GPU。所以第一原则是:按需安装,不要为了“齐全”而装。
如果你确实需要,NVIDIA 驱动安装有两种常见方式。第一种最简单:在“软件和更新”的附加驱动选项卡里,选择 NVIDIA 官方推荐的专有驱动版本,比如 Ubuntu 20.04 对应的一直很稳的 nvidia 520 系列,点应用后重启即可。第二种是去 NVIDIA 官网下载.run驱动文件手动安装,这种方法适合需要特定版本或者系统识别不佳的情况,但过程相对繁琐,而且安装时要在纯命令行模式下进行,稍不注意就会黑屏。
装完驱动验证是否成功,执行nvidia-smi,能看到显卡型号和驱动版本就说明正常。CUDA 的安装建议走官方runfile方式,安装后一定要把环境变量写进~/.bashrc,然后执行nvcc -V验证。
这里我有个亲身的教训:有一年我给一台机器装驱动,直接用了系统更新时自动推送的 NVIDIA 包,结果和系统内核版本冲突,重启后一直卡在登录界面。最后只能在 GRUB 启动菜单进入恢复模式,卸载驱动,再重新安装正确版本。折腾了整整一个下午。所以我的建议是:先备份数据,确认你需要的 CUDA 版本,再对应选驱动版本,别贪新。
4.3 ROS 环境配置(20.04 对 ROS Noetic / ROS2 Foxy)
ROS(机器人操作系统)是无人机软件生态里绕不开的一层,尤其当你做多机协同、机载决策、视觉识别,基本都要通过 ROS 节点进行通信。Ubuntu 20.04 对应的 ROS1 版本是 Noetic,ROS2 版本是 Foxy。如果你是课程指定用 ROS1,直接按官方步骤装 Noetic 即可。
安装步骤不算复杂,但每一步都要细心。首先要设置软件源,把 ROS 官方源加入 apt:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'然后添加密钥:
sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -更新以后安装完整桌面版:
sudo apt update sudo apt install ros-noetic-desktop-full安装完以后初始化 rosdep:
sudo rosdep init rosdep update最后把 ROS 环境变量写进 shell 配置:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc source ~/.bashrc验证安装是否成功,可以启动一个 ROS 主节点,执行roscore,看到started core service的日志就说明正常了。
ROS2 Foxy 的安装逻辑类似,只是软件包名和源不同。这里我必须提醒一个非常常见的坑:不要同时在~/.bashrc里 source ROS1 和 ROS2 的环境,因为它们的环境变量会互相覆盖,导致 ROS 命令不可用。如果你要切换,建议分别写成两个脚本,手动 source。
4.4 PX4 飞控固件工具链(这才是无人机的重头戏)
如果你用的是 PX4 自驾仪,那环境搭建的最后一步就是把 PX4 源码拉下来,装好工具链,跑通仿真。
先安装依赖和编译工具,PX4 官方提供了一步到位的脚本,在源码目录下执行:
git clone https://github.com/PX4/PX4-Autopilot.git --recursive cd PX4-Autopilot bash ./Tools/setup/ubuntu.sh这个脚本会检测系统缺少的包,自动安装包含 CMake、Python、ROS、Gazebo、MAVLink 等在内的所有依赖。但我的经验是:脚本自动安装时有几个包可能因为网络问题失败,执行完后最好自己再跑一遍任务检查一下。而且脚本执行时间取决于网络,经常要二三十分钟,耐心等。
装完后编译 SITL 仿真固件:
make px4_sitl gazebo首次编译会自动下载 Gazebo 模型和依赖库,卡在下载环节很常见,通常是网络问题。如果遇到 Gazebo 模型下载不了,可以用这个命令手动获取:
git clone https://github.com/PX4/PX4-SITL_gazebo最终编译完成后,你会看到 PX4 shell 提示符,同时 Gazebo 窗口弹出四旋翼模型。这一步跑通了,说明你的环境基本合格了。之后再装 QGroundControl 地面站,从官网下载 AppImage 文件,执行chmod +x QGroundControl.AppImage然后运行,就能在图形界面里看到仿真飞机的状态和数据流。
5. 高频问题排查与避坑实录
5.1 环境类问题速查表
我把这一年多被问得最多的问题整理成一个速查表,供大家直接对照排查:
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
make px4_sitl gazebo卡在 90% | 源码不完整,因为编译中断 | 先make clean再重新编译,实在不行重新 clone 源码 |
| 编译时找不到 FastRTPS | 依赖没装全 | 回到 PX4 根目录执行sudo apt install补装缺的包,或重新跑ubuntu.sh |
| QGroundControl 打开黑屏 | 显卡驱动问题或缺少 OpenGL 库 | 更新显卡驱动,安装libglu1-mesa等图形库 |
飞控 USB 连不上,dmesg无输出 | USB 线质量问题或设备损坏 | 换一根短线,插直连 USB 口,不要经过 HUB |
串口设备ttyACM0无法访问 | 用户不在 dialout 组 | 执行sudo usermod -a -G dialout $USER后重启 |
rosdep update超时 | 网络无法访问 raw.githubusercontent.com | 配置代理或改用国内镜像源,手动设置ROSDISTRO_INDEX_URL |
执行rosnode命令报找不到命令 | 环境变量未 source | 确认~/.bashrc末尾有一行 source ROS 的 setup.bash |
| Gazebo 启动后飞机模型沉地 | 模型文件或物理参数异常 | 退出 Gazebo,删除~/.gazebo缓存目录后重试 |
5.2 几个让我印象深刻的“大坑”
第一个坑:编译过程中断后源码损坏。有一次我编译 PX4 时笔记本没插电源,编译到一半电池耗尽直接关机。重启后再编译就频繁报错,错误信息指向一些莫名其妙的头文件缺失。最后我不得不在源码目录里执行make clean,再把整个 PX4-Autopilot 目录删掉重新 clone。这个教训提醒我:编译大型工程之前,确认电源连接稳定,网络连接稳定,好一点的还应该用tmux挂一个会话,防止终端意外关闭导致编译中断。
第二个坑:驱动装错版本后只能重装系统。这是我刚接触 Linux 驱动时最惨痛的经历。当时给一台旧笔记本装 NVIDIA 驱动,没有先查显卡型号,直接用了一个很新的驱动包,结果开机直接卡在黑屏。尝试了很多命令行修复方案都没搞定,最后只能重新安装系统。从那以后,我养成一个习惯:任何涉及内核模块的安装,先在论坛或官方文档查清楚对应版本,并且一定要先做系统备份。Ubuntu 自带的timeshift就很适合做系统快照,装驱动前拍一个快照,出了问题恢复也就几分钟的事。
第三个坑:/home分区满了导致编译失败。PX4 编译过程会产生大量中间文件和仿真模型,如果/home分区只给了几十 GB,很容易在编译中提示 “No space left on device”。排查时用df -h一看,根目录还有几十 GB,但/home已经满了。这种分区不合理的场景很尴尬,因为扩容比较麻烦。建议安装系统时把/home和/划分清楚,也可以定期清理~/.gazebo、~/.cache、~/.ros/log这类缓存目录。
第四个坑:用虚拟机跑 Gazebo 白白浪费三个小时。有一次我给刚入门的同学远程指导环境搭建,他用的是 VMware,结果装完 PX4 工具链,一启动 Gazebo 就卡死,CPU 占到 100%,图形界面完全不动。我们折腾了很久,最后我把虚拟机设置里的 3D 加速打开、显存调到 128MB,才勉强能转起来。但帧率仍然很低,根本没法做仿真实验。所以如果你计划做任何和图形仿真、点云可视化相关的工作,建议从一开始就别用虚拟机,省下的时间用来写代码不香吗。
写在最后的体会
环境搭建这件事,在整个无人机开发的大盘子里,往往是被低估的。很多人以为写代码、调算法才是核心,结果真正做起来,第一周全耗在装系统、装驱动、配依赖上。这不是浪费时间,而是必经之路——只有把基础工具链摸清了,后面不管是跑仿真、分析日志、调参,还是部署到机载电脑上,你才不会被环境问题反复打断思路。
我个人在实际操作中的体会是,环境搭建最讲究“记录”。每成功一步,就把命令和踩坑点记下来,不要相信自己的记忆力。我自己就维护了一个环境搭建笔记,里面记录了当前机器装了什么版本的 ROS、PX4、CUDA,Python 环境怎么管理的,遇到问题的解决方式是什么。后来换新电脑,照着笔记不到半天就配好了完整环境——这是最值得投入的时间。
最后再分享一个小技巧:把所有环境配置文件(~/.bashrc、/etc/udev/rules.d/下的规则、PX4 编译脚本的修改记录)放进一个 Git 仓库里管理。这样即使系统重装,你也能快速恢复,还能追溯每次改动的原因。这算是我这几年被装环境折腾之后总结出来最实用的一条经验了。