news 2026/9/6 12:05:50

无人机开发必备:Ubuntu 20.04 与 Linux 工程基础环境搭建实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
无人机开发必备:Ubuntu 20.04 与 Linux 工程基础环境搭建实战指南

做无人机开发这条路,Module 3 是我个人觉得最该静下心啃的一块。它不涉及任何飞控算法,也不写一行飞机代码,却决定你后面所有模块能不能顺利跑起来。这个模块的名字叫 Ubuntu 20.04 + Linux 工程基础——单看名字很基础,但实际踩坑的人不在少数。简单说,这套环境就是我们后续写代码、编固件、跑仿真、连飞控的工作台;而 Linux 工程基础,则是你在工作台上不撞翻工具、不迷路的基本功。这篇文章我就按自己实际动手的过程,把这套无人机软件开发环境从零搭到能用的经验和教训一次说清楚,适合刚开始学无人机开发、或者装了 Ubuntu 但不知道怎么高效用起来的同学。

1. 为什么无人机软件开发的底座选 Ubuntu 20.04

1.1 无人机开源生态与 Ubuntu 的强绑定关系

先聊一个很多人会问的问题:为什么无人机开发非得用 Linux?用 Windows 不行吗?

答案是:能,但非常难受。PX4、ArduPilot、MAVSDK、ROS/ROS 2 这套无人机软件栈,从源码编译、依赖管理到设备驱动,几乎所有官方文档和 CI 流程都默认跑在 Ubuntu 上。你用 Windows 的话,要么得手动去折腾 Cygwin、WSL,要么各种脚本根本跑不通,光是环境问题就能劝退一大半人。

关键原因有三个。第一,包管理。Ubuntu 基于 Debian,apt 这套包管理工具在安装依赖时太方便了,你装一个软件,它自动把编译时需要的头文件、运行时需要的库都拉齐,这在 Windows 上很难想象。第二,驱动和工具链。飞控的 USB 串口驱动、相机驱动、NVIDIA 驱动,以及后面要用的交叉编译工具链,几乎都是先在 Linux 上支持,Windows 版本经常滞后或干脆没有。第三,社区惯性。你遇到问题去搜解决方案,十有八九搜到的是 Linux 下的命令和操作,如果自己不用 Linux,连别人的解决方案都读不懂。

所以做无人机开发,Ubuntu 几乎是避不开的选择。它不是“最佳选择”,而是整个生态的“默认选择”。

1.2 版本选型:不是越新越好

版本上有一个常见的误区,很多新手一看 Ubuntu 都出到 24.04 了,就直接装最新版,结果后面处处碰壁。

我的建议非常明确:现阶段学无人机开发,Ubuntu 20.04 依然是最稳的中间版本。原因也简单,整个开源飞控生态的版本推进是有延迟的。

以 ROS 为例,ROS 1 的最后一个版本 Noetic 官方支持的就是 Ubuntu 20.04,很多无人机课程、论文代码、开源项目都基于 Noetic 写的。PX4 的编译环境在 20.04 上被验证的次数最多,遇到问题最容易搜到答案。ArduPilot 虽然对 22.04 支持得也不错,但很多老一点的教程和工具脚本还是按 20.04 写的。

从内核角度讲,Ubuntu 20.04 默认内核是 5.4,它对新硬件的兼容性可能不如 22.04 的 5.15 内核,但对飞控相关的 USB 转串口芯片(CH340、CP210x、FTDI)支持非常成熟,反而是某些太新的内核偶尔会和特殊 USB 芯片出现兼容性问题。

我整理了一个版本对比表,比较直观:

版本对应 ROS 版本内核版本无人机生态成熟度推荐程度
Ubuntu 18.04ROS Melodic4.15偏老,部分新固件编译不过不推荐新手
Ubuntu 20.04ROS Noetic5.4资料最多、套路最熟强烈推荐
Ubuntu 22.04ROS 2 Humble5.15ROS 2 为主,PX4 支持尚可可尝试,但资料少
Ubuntu 24.04ROS 2 Jazzy6.8太新,踩坑无参考不推荐现在用

一句话总结:学习阶段,你的目标不是追求最新版,而是追求“踩坑时有人替你踩过”。选 20.04 等于选了一个防御值最高的版本。

1.3 虚拟机、双系统、WSL 怎么选

环境确定之后,下一个问题就是:装在哪儿?

我见过三种主流的装法:虚拟机、双系统、WSL 2。这里直接说结论:如果你是认真学无人机开发,优先双系统;如果只是先体验一下,可以用虚拟机;WSL 2 不建议作为主力环境。

虚拟机的优点是安全、方便,在 Windows 窗口里跑一个 Ubuntu,随时快照、随时删除。VMware Workstation 或者 VirtualBox 都行。缺点是性能损失,尤其是 USB 设备透传和图形加速这块,跑 Gazebo 仿真时掉帧很明显。如果你只是敲命令、学 Linux 基础,虚拟机完全够用。

双系统是更“正统”的做法。Ubuntu 直接跑在真机上,CPU、内存、GPU 性能全部释放,后面编译 PX4 固件、跑 Roslaunch、用 QGroundControl 连接飞控都更顺畅。缺点是安装时需要给 Ubuntu 划分硬盘空间,装机过程对新手稍微有点门槛,而且 Windows 和 Linux 引导共存偶尔会出现启动项丢了的状况,但都有成熟解决方案。

WSL 2 是微软做的 Linux 子系统,性能比虚拟机好,但问题出在设备访问上。飞控、串口、USB 摄像头这些外设的透传,WSL 2 处理得比较别扭,虽然新版支持 usbipd 工具可以把 USB 设备挂进去,但经常有莫名其妙的权限和驱动问题。做无人机开发不建议把时间耗在这上面。

我的实际建议是:如果电脑配置还过得去,硬盘有 150GB 以上空闲空间,直接上双系统。如果只是临时学习、暂时不想动磁盘分区,先用虚拟机撑过 Module 3 基础阶段也没问题,等做到真机联调之前再切双系统。

2. 搭建环境前必做的准备工作

2.1 镜像下载与校验

确定方案后,第一步是下载 Ubuntu 20.04 的 ISO 镜像。这里有一条很关键的原则:只从 Ubuntu 官网或国内知名高校镜像站下载,不要用网上流传的第三方修改版。

第三方修改版可能植入了不明驱动、后门脚本,或者擅自改动了系统配置,一旦用了,后面出了问题你根本不知道是自己操作的问题还是镜像被人动过手脚。官方镜像地址是 ubuntu.com/download,国内可以从清华大学、阿里云、中科大的开源镜像站下载对应版本。

下载完 ISO 之后,建议做一步校验。官方页面会提供 SHA-256 校验值,在 Windows 上可以用 PowerShell 执行Get-FileHash .\ubuntu-20.04.6-desktop-amd64.iso查看文件哈希值,然后和官网给出的值比对。如果不一样,说明文件下载不完整或已被篡改,不要使用。这一步很多人会跳过去,但实际中镜像传输断掉导致安装到一半报错的情况并不少见。

写入 U 盘的工具,我推荐 balenaEtcher 或者 Rufus。Rufus 在 Windows 下很好用,写入时分区类型建议选 GPT,目标系统类型选 UEFI(非 CSM),这样对现在的主流主板兼容性最好。也可以直接用 dd 命令:sudo dd if=ubuntu-20.04.6-desktop-amd64.iso of=/dev/sdb bs=4M status=progress && sync,这里的/dev/sdb是你的 U 盘设备名,千万不能写错,否则会把其他盘抹掉。

2.2 安装过程的关键点与分区规划

把 U 盘插上,开机按 F12 或 Del 进入启动菜单,选择 U 盘启动,就能进入 Ubuntu 安装界面。看起来就是一路点“继续”就行,但有三个地方值得注意。

第一个是安全启动(Secure Boot)的设置。如果你的电脑预装 Windows 11,BIOS 里的 Secure Boot 默认是开启的。Ubuntu 20.04 官方镜像支持 Secure Boot,安装时一般没问题,但后面如果自己装 NVIDIA 显卡驱动或者一些内核模块,偶尔会出现签名校验失败的情况。如果遇到这类问题,可以从 BIOS 里关闭 Secure Boot 再试。不过要注意,关闭 Secure Boot 后,某些 Windows 功能(如 BitLocker 加密)可能会受影响,操作前保障好自己的数据。

第二个是安装类型。一定要选择“Something else”(其他选项)手动分区,不要选“Erase disk and install Ubuntu”,否则整个硬盘数据就没了。我推荐的分区方案是:

分区大小类型挂载点
/boot/efi512MBEFI 系统分区/boot/efi
/50GBext4/
/home剩余空间ext4/home
swap16GBswap

有人会问,为什么要单独把 /home 分出去?因为系统盘挂掉或重装系统时,/home 里存的项目源码、配置文件、下载的固件都能保留,只需要重新挂载就行。另外,单独分一个 swap 分区,在编译大型项目时内存不够可以作为后备,虽然现在内存普遍 16GB 以上,但 PX4 编译时并行的编译器进程很容易把内存吃满,有个 16GB 的 swap 兜底,能少很多 OOM(内存耗尽)的崩溃。

第三个是联网和更新。安装过程中如果检测到网络,会提示“Download updates while installing Ubuntu”,建议取消勾选,等装完系统再换源批量更新。否则默认源在国外,下载速度很慢,白白浪费时间。

2.3 装机后的第一件事:换源与系统更新

系统装好后,进入桌面,别急着装软件,先做两件事:换软件源和系统更新。

Ubuntu 默认的软件源服务器在国外,在国内网络环境下执行apt update会非常慢。换源的本质是把/etc/apt/sources.list文件里的下载地址替换成国内镜像站的地址。用清华、阿里、中科大任一镜像源都行。我以中科大源为例:

先备份原来的源文件:

sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

然后用编辑器打开/etc/apt/sources.list,把里面的archive.ubuntu.com全部替换为mirrors.ustc.edu.cn。可以用sed命令快速完成:

sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list sudo sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

之后刷新索引并升级系统:

sudo apt update sudo apt upgrade -y

第一次升级会有大量软件包更新,耗时取决于网速,一般 10~20 分钟。这一步做完,系统就处于一个相对干净、最新的状态,后面装开发环境不容易出现依赖版本过旧的问题。

3. Linux 工程基础:无人机开发的日常高频命令

3.1 文件系统与目录结构:先建立“一切皆文件”的心智模型

Windows 用户刚切到 Linux 时,最大的困惑就是“我的 C 盘 D 盘呢?”Linux 不搞盘符,根目录是/,所有设备和分区都挂在根目录下的不同挂载点。这不是设计倒退,而是一种更统一的抽象模型——设备、进程、配置全是文件,都能用同一套工具操作。

无人机开发中你经常接触的目录基本固定在几个地方。/home/你的用户名/是家目录,你的代码、下载、文档都在这里。/etc存放系统配置,比如换源改的sources.list就在这里。/dev是设备文件目录,飞控插上 USB 后出现的/dev/ttyACM0就在这里面。/var/log存日志,排查问题经常要看。/opt一般放第三方大型软件,比如后面可能会装的 QGroundControl。

基础的命令必须形成肌肉记忆。cd切换目录,ls列出文件(ls -l查看详细信息,ls -a查看隐藏文件),cp复制,mv移动或重命名,mkdir -p递归创建目录,rm -rf递归强制删除。我要特别提醒一句:rm -rf非常危险,尤其是在 root 权限下执行时,一个字母输错就可能把系统文件删了。我见过有人把/home写成/home(多了一个空格),结果把家目录下的文件全删了。使用rm之前,先ls确认路径。

软链接在无人机项目里也很常用。比如你习惯了快速访问某个路径很深的工程目录,可以建一个软链接:

ln -s /home/yourname/work/px4/Firmware /home/yourname/px4

之后cd ~/px4就等于进入了那个深层目录。这个技巧能省不少事。

环境变量也是 Linux 工程基础里的重点。PATH环境变量决定了你在任何路径下输入命令时,系统去哪里找可执行文件。比如你把交叉编译工具链解压到了/opt/toolchain/bin,想让aarch64-linux-gnu-gcc全局可用,就需要把目录加入 PATH:

export PATH=/opt/toolchain/bin:$PATH

export只管当前终端窗口,想永久生效,要写进~/.bashrc~/.profile文件末尾。无人机开发中经常要用到环境变量,比如 ROS 的ROS_MASTER_URI、PX4 仿真时的PX4_SIM_MODEL,都是在 shell 里设置的,这一块最好搞懂。

3.2 用户与权限:无人机开发中绕不开的坑

权限问题是我见过最多人卡壳的地方,也是 Module 3 必须吃透的核心知识点。

Linux 是一个多用户系统,文件都有属主和权限位。在终端执行ls -l,你会看到类似-rw-r--r-- 1 user group 1024 Mar 10 10:00 file.txt的输出。开头那一串字符,第一个是文件类型(-表示普通文件,d表示目录),后面九个字符每三个一组,分别表示属主、属组、其他用户的权限。r读、w写、x执行。

数字权限表示法很实用。r=4,w=2,x=1,把三者相加得到一个数字。比如chmod 754 file,意思是属主有读+写+执行(7),属组有读+执行(5),其他人只有读(4)。chmod 664是常见的文件权限(属主和属组能读写,其他人只读),chmod 755是常见的目录和可执行文件权限。

为什么无人机开发特别容易碰到权限问题?因为飞控、数传模块的 USB 串口设备默认属于dialout用户组,而普通用户不在这个组里,所以一运行 QGroundControl 或cat /dev/ttyACM0,就会报 Permission denied。解决办法是把自己加进dialout组:

sudo usermod -aG dialout $USER

执行完必须重新登录(退出重进或重启)才生效。还有一个组叫sudo,加入这个组的用户可以用sudo执行管理员命令:

sudo usermod -aG sudo $USER

新建用户时,推荐使用adduser而不是useradd,因为前者交互式地帮你创建家目录、设置密码、填用户信息,后者参数多且容易漏。需要看了:sudo adduser newuser一行搞定。

这里的底层逻辑是:Linux 用权限控制避免普通用户误操作系统文件;而我们的日常开发需求,只需要把自己加到合适的附加组即可,不要图省事直接用 root 干活。保持“最小权限”原则,养成好习惯,后面在服务器上搞部署时才不会捅篓子。

3.3 进程、网络与日志排查命令

调试无人机时,你经常会遇到“程序跑起来了但没反应”“电脑突然很卡”“串口连不上”这类问题。这时候靠鼠标点界面是不够的,必须学会在终端里“体检”。

查看进程,最常用的是ps aux | grep 关键词。比如你想确认 QGroundControl 是不是在后台卡住了:

ps aux | grep QGroundControl

管道符|的作用是把前一个命令的输出交给后一个命令处理,grep负责按关键词过滤,这个组合是排查问题的基础操作。如果进程状态是Z(僵尸进程)或者 CPU 占用 100%,基本可以判断它出了问题。

动态查看系统资源的命令是top,进阶版是htophtop显示的彩色界面能直观看到 CPU、内存占用和每个进程的 CPU 使用率,想杀掉某个卡死的进程,直接在界面按 F9 选中 SIGKILL。命令行里杀进程用kill PID,强杀用kill -9 PIDkill发送的是 SIGTERM 信号,给进程一个优雅退出的机会;kill -9则是强制终止,系统直接回收资源。能先用kill就先不用-9,强制杀可能造成数据未写完。

网络方面,查看本机 IP 用ip addr(老命令ifconfig在新系统上需要额外装 net-tools),测试能否 ping 通外部设备用ping。无人机开发中经常需要知道飞控板或树莓派的 IP 地址,尤其是后面做数传、SSH 远程登录时,这俩命令很常用。查看端口监听情况用ss -tunlp,可以确认某个端口是不是被占用了。

系统日志也是重要的排查工具。systemd是现代 Linux 的服务管理机制,日志统一交给 journald 管理。查看系统启动以来的错误日志:

journalctl -xe

如果串口设备插上后没反应,可以看内核日志:

dmesg | tail -20

这里可能会看到ch341-uart或者cp210x的字样,说明 USB 转串口芯片已被识别。配合ls /dev/ttyUSB*能确认设备节点名。

还有两个基础的容量命令不能漏:df -h查看磁盘剩余空间(编译大项目时磁盘满了会报诡异的错),free -h查看内存和 swap 使用情况。养成习惯,环境出问题先看资源、看日志、看进程,基本能解决 80% 的疑难杂症。

4. 无人机场景下的核心工具链配置

4.1 基础开发工具链:一键装齐的思路

环境配置到这一步,系统已经能正常用了。接下来要装的是无人机开发常用的工具链。我的原则是:不要试图一次性装一堆“以后可能会用到”的软件,而是按项目需要渐进式安装。但下面这几样属于基础中的基础,建议先装好:

sudo apt install -y build-essential git cmake python3-pip vim htop net-tools curl

build-essential组包含了 gcc 编译器、g++、make 等编译必备工具。很多新手直接运行make发现找不到命令,就是因为没装这个包。git不用多说,开源项目协作的生命线。cmake是当前 C/C++ 项目的主流构建系统生成器,PX4、ArduPilot 的源码构建都会用到。python3-pip是 Python 的包管理工具,MAVSDK-Python、各种地面站脚本依赖它。vim是终端文本编辑器,虽然新手会觉得难用,但后期在服务器上改配置时离不开它。

这里有一个很重要的点:Ubuntu 20.04 自带 Python 3.8,系统很多底层工具(比如 apt 的某些模块)依赖它。千万不要手贱去卸载系统自带的 Python,也不要随意把默认的python3指向其他版本,否则可能导致系统包管理器崩溃。你想用新版本 Python,用venv建虚拟环境或者装pyenv管理,而不是动系统 Python。这是 Linux 运维和开发中一个常见的“血泪教训”。

安装完成后验证一下:

gcc --version cmake --version git --version

如果都能输出版本号,说明基础工具链已经就位。

4.2 源代码管理:Git 的正确用法

无人机开发几乎离不开 Git 和 GitHub/Gitee。PX4 源码、ArduPilot 源码、ROS 功能包,都是从远端仓库 clone 下来之后,在自己分支上修改、调试、再提交的。

最基本的流程是:git clone 仓库地址获取源码;git checkout -b 新分支名创建并切换到自己的工作分支;修改代码后用git add添加改动、git commit -m "描述"提交到本地;最后git push推送到远端。

无人机项目里有个特别的坑是子模块(submodule)。PX4 的 Firmware 仓库里引用了很多外部库,比如 mavlink、uavcan、pyulog,它们不是放在主仓库里的,而是以 submodule 的形式关联。直接git clone之后,子模块目录是空的,必须再执行:

git submodule update --init --recursive

这个命令会递归地把所有子模块下载到对应的目录。经常有人只 clone 了主仓库就开始编译,结果报一堆找不到头文件的错误,其实就是没更新子模块。

还有一个习惯要养成:每次编译之前,先git pull拉取最新代码。开源项目更新很快,尤其是 PX4 每天的提交非常多,锁定一个稳定的 release 分支(比如v1.13.3)比跟着主分支漂移要省心得多。

我在项目里常用git log --oneline --graph查看提交历史,用git diff看修改内容,用git stash暂存当前未提交的改动。这些命令在实践中会反复出现,不建议死记,用多了自然就熟了。

4.3 串口、SSH 与交叉编译:连接飞机与开发板

工具链里和“连硬件”相关的部分,是无人机开发比较特殊的地方。

首先是串口和 USB 设备。飞控、数传模块、GPS 模块通常通过 USB 转串口芯片连接电脑,设备节点一般是/dev/ttyACM0/dev/ttyUSB0。读取串口数据最轻量的方式是:

sudo apt install -y screen screen /dev/ttyACM0 115200

screen会以 115200 波特率打开串口终端。按Ctrl+A然后K退出连接。有的同学喜欢用minicompicocom,功能都差不多,选一个用顺手就行。

需要提醒的是,串口设备是独占的。如果你已经用 QGroundControl 连接了飞控,再用screen打开同一个串口,就会报设备忙(Resource busy)。所以排错时要先确认没有其他程序占用该设备。

其次是 SSH 远程登录。当你需要把代码部署到机载电脑(比如树莓派、NVIDIA Jetson)上时,通常不会接显示器键盘操作,而是通过 SSH 从自己的 Ubuntu 电脑远程连过去:

ssh user@192.168.1.100

为了免密登录,可以在本机生成密钥并拷贝到目标机器:

ssh-keygen -t ed25519 ssh-copy-id user@192.168.1.100

之后ssh登录就不再要密码了。文件传输用scp或者rsync,后者支持增量同步,传输大文件夹时比scp高效很多:

rsync -avz ./build/ user@192.168.1.100:/home/user/workspace/build/

最后是交叉编译,这个概念无人机开发者必须搞清楚。

我们平时在电脑上直接编译,生成的程序只能在 x86_64 架构的 CPU 上运行。但机载电脑如果是树莓派(ARM 架构)或者 Jetson(ARM 架构),那 x86 编译出来的程序是跑不了的。交叉编译的意思就是:在 x86 主机上,用针对 ARM 的编译器,生成能在 ARM 目标板上运行的程序。

简单示例,安装 ARM 交叉编译工具链:

sudo apt install -y gcc-aarch64-linux-gnu

然后编译一个 C 程序:

#include <stdio.h> int main() { printf("Hello from ARM!\n"); return 0; }
aarch64-linux-gnu-gcc hello.c -o hello_arm

file hello_arm查看生成的文件格式,会看到ELF 64-bit LSB executable, ARM aarch64,说明这个程序只能在 ARM 上运行。把它传到目标板上,即可执行。

在真实项目中,PX4 固件交叉编译到 Pixhawk 系列飞控(ARM Cortex-M 架构)时,用的就是类似思路,只不过编译过程由 PX4 的构建脚本自动完成。大型工程里交叉编译还有一点很关键:目标板上的动态链接库必须和交叉编译时使用的库匹配。嵌入式 Linux 项目里经常出现宿主机上编译好的程序,拷到板子上就报cannot find shared library,原因就是库路径或版本不一致。所以,优先使用目标板厂商提供的 SDK 或工具链,不要自己随便抓一个编译器硬上。这也解释了为什么搜索热词里“安装 petalinux 及 zynq7000 交叉编译工具”这类问题被频繁搜索——Xilinx Zynq 平台上的开发,Vitis/PetaLinux 工具的版本匹配要求非常严格,踩坑的源头基本都是工具链不配套。

另外,无人机遥测数据经常通过 MQTT 协议上报地面站或者云端服务器。Ubuntu 下调试 MQTT 建议装一个mosquitto-clients

sudo apt install -y mosquitto-clients

订阅主题和发布消息分别用mosquitto_submosquitto_pub,排查数据链路时很好用。

5. 环境搭建常见问题与排查实录

5.1 USB 串口相关的三板斧

无人机开发中接触最多的硬件就是飞控板,连接时最典型的报错是:

PermissionError: [Errno 13] Permission denied: '/dev/ttyACM0'

原因前面说过,当前用户不在dialout组。执行:

sudo usermod -aG dialout $USER

然后注销重新登录,问题就能解决。

如果设备节点根本没出现,先用lsusb看看 USB 设备是否被识别。能看到类似1a86:7523这样的输出,表示 CH340 芯片已连接;如果没有,检查 USB 线是不是只能充电不能传数据——这种线在嵌入式调试中非常坑,换了数据线就能解决。如果lsusb能看到设备但/dev/ttyACM0没出现,多半是内核缺驱动,CH340 和 CP210x 驱动通常已内置,老版本内核可能需要手动加载:

sudo modprobe ch341 sudo modprobe cp210x

还有一个小技巧是固定设备名。当电脑同时插了多个串口设备时,/dev/ttyACM0/dev/ttyUSB0的编号会根据加载顺序变化,导致脚本经常找不到设备。解决办法是写一个 udev 规则,根据设备的 USB 序列号或厂商 ID 生成固定的软链接。这个属于进阶操作,但非常实用,保存环境变量时可以参考:

sudo echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="flight_controller"' > /etc/udev/rules.d/99-usb-serial.rules sudo udevadm control --reload-rules

之后无论插拔多少次,设备节点都会是/dev/flight_controller

5.2 编译错误与内存不足的排查套路

编译 PX4 或 ROS 功能包时,经常遇到类似的报错,新手一看满屏红字就慌了,实际上多数问题只需按顺序排查。

第一步看是不是依赖缺失。CMake 报Could not find a package configuration file provided by "XXX",说明缺了某个开发包。解决办法是搜索对应的 apt 包名:

apt search 库名 sudo apt install 库名-dev

经验是:带-dev后缀的包是编译时需要的头文件和链接库,别只装不带后缀的运行库。

第二步是处理内存不足(OOM)。大型工程并行编译时,如果电脑内存只有 8GB 或 16GB,make -j8经常会卡死或崩溃。推荐根据内存设置并行数:内存 16GB 用-j4,32GB 用-j8。安全起见,先用free -h看剩余内存再决定。还有一招是扩大 swap 空间:

sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

这样在编译高峰期有个缓冲,至少不会直接被杀进程。

第三步是清理旧的编译缓存。PX4 这种大项目,改了环境变量或切换了版本后,旧的构建缓存会导致莫名其妙的编译错误。遇到这种情况,直接删除 build 目录重新构建往往是最快的办法:

rm -rf build make px4_sitl gazebo

5.3 网络、源和环境变量类问题

换了镜像源之后,有时执行apt update会报The following signatures couldn't be verified because the public key is not available。这是因为源仓库的 GPG 公钥没有更新。解决办法是添加对应源的公钥,以 ROS 源为例:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 公钥ID

不过apt-key在新版 Ubuntu 中已废弃,更正规的做法是把公钥放到/etc/apt/trusted.gpg.d/目录下,这里不展开了。遇到这类报错,通常网上能搜到官方给出的添加公钥命令,照着做就行。

还有一类问题是环境变量冲突。装了 ROS 之后,~/.bashrc里会多出source /opt/ros/noetic/setup.bash之类的语句。如果你同时用了多个版本的 ROS,或者自己定义了PYTHONPATH,可能会遇到导入模块异常或者命令找不到。排查时执行:

env | grep -E 'ROS|PYTHONPATH'

看输出的变量是否符合预期。ROS 多机通信时,ROS_MASTER_URIROS_IP这两个变量特别容易被忽略,导致两台电脑明明 ping 得通,话题却收不到。这类问题看着像网络故障,实际是环境变量配置错误。

网络问题的另一个高发点是 DNS。如果你发现ping 192.168.1.1正常,但ping baidu.com解析不出地址,说明是 DNS 配置问题。修改/etc/systemd/resolved.conf里的DNS字段,或者直接编辑/etc/resolv.conf指向公共 DNS 服务器(例如 223.5.5.5)就能解决。

桌面环境相关的坑也提一嘴。如果你用的是 NVIDIA 显卡,Ubuntu 20.04 装机后进入系统桌面卡顿、分辨率不对或者频繁闪屏,大概率是默认用的开源驱动 nouveau 和 NVIDIA 显卡不兼容。解决方案是安装官方驱动:

sudo ubuntu-drivers autoinstall sudo reboot

安装完重启后,执行nvidia-smi能看到显卡信息,说明驱动正常。这一步对后面跑基于 CUDA 的视觉识别程序尤其重要。

我把上面这些问题整理成一个速查表,方便对照:

现象可能原因推荐排查方向
串口 Permission denied不在 dialout 组sudo usermod -aG dialout $USER
找不到 /dev/ttyACM0USB 线/驱动问题lsusbdmesg、换数据线
CMake 找不到依赖包缺少 -dev 包apt search、安装对应开发包
编译被 OOM 杀死内存不足减少-j并行数、加 swap
apt update 密钥报错GPG 公钥缺失添加仓库官方公钥
DNS 解析失败只配了内网 DNS修改 resolved.conf
桌面卡顿/闪屏nouveau 驱动不稳定ubuntu-drivers autoinstall

6. 从环境到工程:我的实操经验与学习建议

6.1 不要背命令,先跑通一个能看见结果的小任务

到了这一步,你的 Ubuntu 20.04 环境已经可以支撑无人机开发了,但离“真正上手模块后续内容”还差一个习惯上的转变。

学 Linux 最常见的一个误区是拿它当考试科目去背命令清单。我在带新人时经常说一句话:命令是查出来的,不是背出来的。每个命令都有man 命令名命令名 --help可以查帮助,tab键可以补全路径和命令,真正需要死记的根本没几个。与其花一晚上抄命令大全,不如亲手跑通一个完整的小任务。

比如给自己定一个目标:写一个 Python 脚本,读取飞控通过串口发送的 NMEA 数据,解析出经纬度并打印到屏幕上。这个任务会强迫你用到串口配置、文件读写、Python 脚本执行、管道和权限管理,一次做下来比看十篇教程都管用。再比如把 PX4 的 Gazebo 仿真跑起来,看着虚拟无人机起飞,你会对工具链的完整流程有更直观的感知。

6.2 环境配置工作流与个人开发习惯

最后分享几个我摸索出来的工作流习惯,特别是环境配置这种容易踩坑的事情。

第一,把环境安装过程写成脚本。比如你所有的新电脑都需要装同一批基础工具,就写成一个 shell 脚本:

#!/bin/bash sudo apt update && sudo apt upgrade -y sudo apt install -y build-essential git cmake python3-pip vim htop sudo usermod -aG dialout $USER echo "Environment setup complete!"

以后换机器、重装系统,一行命令就跑完基础配置,不用再一个个手动点。这也是“工程基础”四个字的意义——用工程化的思维管理自己的开发环境。

第二,给高频命令设置别名。编辑~/.bashrc,添加:

alias gs='git status' alias gp='git pull' alias py='python3' alias c='clear' alias ll='ls -alF'

然后执行source ~/.bashrc立即生效。这种小优化积累多了,日常操作效率会提升很多。

第三,项目目录保持干净和统一。我个人的习惯是:

~/workspace/ ├── px4/ # 飞控固件源码 ├── ros/ # ROS 功能包 ├── scripts/ # 自用脚本 ├── docs/ # 笔记和参考资料 └── build/ # 临时编译产物

编译产物永远不要混在源码目录里,日志和下载文件定期清理。这样不仅自己看着舒服,后面调试定位问题时也更清晰。

第四,上来就开一个 Git 仓库管理自己的笔记和环境配置文件。哪怕只有一个notes.md也要用版本控制,记录下每天遇到的问题和解决方案。时间长了,这份笔记就是你最强的排错手册。我自己前两年积累的踩坑笔记,现在回头看比很多博文都实用,因为每一行记录都对应着一次真实的问题定位过程。

在指导过不少新人之后,我的体会是:Module 3 这类内容看起来不如飞控算法有成就感,但几乎所有后期“卡壳”都能追溯到环境或者 Linux 基础没打牢。我第一次带飞控调试时,单是搞懂串口权限和设备名字就花了一下午;后来踩的坑多了才发现,那些能对着满屏编译日志气定神闲定位问题的人,不是因为天生会用 Linux,而是因为他们把基础工具和工作流磨成了本能。所以别急,把命令敲稳,把工具链跑通,把每个报错都查到底,后面写代码、调参、联调的时候,你会感谢现在这个愿意花时间打地基的自己。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 12:04:41

二手iPhone换电池验机指南:识别真伪与避坑技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 12:02:52

SPSS信效度检验全流程:Cronbach‘s Alpha与KMO因子分析详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 11:57:43

儿童过敏调理赛道迎来新参照 蓝帽牛初乳儿童适配性成关注焦点

近期随着春季花粉季临近&#xff0c;国内儿童过敏性鼻炎调理相关搜索量环比上涨127%&#xff0c;合规蓝帽牛初乳作为低风险的免疫调理方向&#xff0c;正在成为不少家长的关注选项。从行业背景来看&#xff0c;据中国妇幼保健协会发布的最新调研数据&#xff0c;我国0-14岁儿童…

作者头像 李华
网站建设 2026/9/6 11:57:40

嵌入式开发必知:TCP/IP协议栈四层模型与实战调试

嵌入式开发做到一定阶段&#xff0c;几乎都会碰到网络。不管你是做智能家居、工业网关&#xff0c;还是搞车载设备&#xff0c;只要设备需要联网或者远程通信&#xff0c;TCP/IP这套模型就绕不开。不少朋友一上来就调接口、看demo&#xff0c;现象是灯亮了、数据通了&#xff0…

作者头像 李华
网站建设 2026/9/6 11:53:42

RISC-V切入AI芯片的三种姿势:自定义指令、RVV与NPU异构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 11:53:27

Python+Spark+Hadoop淘宝化妆品数据分析系统毕设方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华