我们在搞无人机软件开发时,最容易被忽略、也最影响后续效率的一件事,就是基础环境。很多朋友一上来就急着写代码、调飞控,结果编译PX4源码时装错依赖、交叉编译链版本不对、串口权限没配好,一个下午就耗在莫名其妙的问题上。Module 3这块内容,说白了就是把Ubuntu 20.04当成无人机软件开发的主战场,把Linux工程基础打牢,让后面的飞控固件编译、机载计算机通信、仿真测试都能顺顺利利跑起来。
这篇文章我就从实际踩坑经验出发,把整个环境搭建和Linux工程入门的关键环节拆开揉碎讲清楚。不管你是准备做PX4/ArduPilot二次开发,还是打算搞ROS机器人操作系统与无人机对接,或者只是想给飞控板搭个稳定的编译环境,这篇内容都适合先过一遍。
1. 内容整体设计与思路拆解
1.1 为什么无人机软件开发绕不开Ubuntu 20.04
先说结论:在无人机软件开发这条路上,Ubuntu 20.04是目前兼容性最好的“安全牌”。PX4官方文档长期把Ubuntu 20.04作为推荐编译环境,ROS Noetic(ROS1的最后一个长期维护版本)也基于它开发,MAVSDK、QGroundControl这些地面站工具链同样在20.04上测试最充分。
有的朋友可能会问:Ubuntu 22.04、24.04都出了那么久,内存更大、内核更新,为什么不用更新的版本?我一开始也这么想,直到被现实教育了。Ubuntu 22.04虽然也能装PX4环境,但Gazebo仿真版本、Python依赖、以及一些飞控厂商提供的SDK,并没有完全跟上新系统的节奏。尤其是做硬件在环仿真(HITL)时,USB转串口驱动、飞控固件烧录工具,对老版本Ubuntu的兼容性明显更好。
这里有个很实在的点:无人机开发不在乎“尝鲜”,而在乎“稳定可复现”。你写出来的代码是给飞控跑的,不是给操作系统当小白鼠的。所以Ubuntu 20.04 + LTS(五年长期支持)版本,能保证你的开发环境和官方文档对得上,别人遇到的坑你大概率不会遇到。
1.2 这套环境的三大核心模块划分
整个无人机软件开发环境,我在实际教学和项目里习惯分成三个层次来搭建:
- 底层系统层:Ubuntu 20.04安装、网络配置、软件源优化、基本驱动。这是地基,地基本来就不稳,上层全白搭。
- 命令行与工程工具层:Shell操作、文件权限、压缩解压、进程管理、Git版本控制、编译工具链。这一层是“手”和“脚”,你所有操作都靠它们完成。
- 无人机专用开发栈:交叉编译工具、PX4/ArduPilot源码环境、MAVLink通信协议相关工具、串口与USB设备权限配置。这一层是“武器”,直接对飞控硬件工作。
很多人学Linux只学了一堆命令,不知道这些命令在无人机开发里到底怎么用,最后就是“学过但不会用”。我写这篇文章的思路,就是把每一层知识都挂靠到具体的无人机开发场景里,让你明白“学这个命令是为了解决什么问题”。
2. 环境搭建第一步:Ubuntu 20.04安装与初始化配置
2.1 双系统还是虚拟机:一个需要认真思考的选择
关于Ubuntu 20.04的安装方式,我先泼一盆冷水:如果你打算长期做无人机开发,建议直接装双系统,不要用虚拟机做主力环境。
虚拟机(比如VMware)的好处是方便、可以快照回滚,Windows里直接跑Linux,切换不用重启。但无人机开发里有几个场景,虚拟机动不了:
- USB设备直通:飞控通过USB连接电脑时,虚拟机需要配置USB passthrough,而且经常出现掉线、权限错乱的问题。我见过太多人在VMware里折腾飞控连接,最后发现是USB控制器版本不兼容。
- 实时性要求:Gazebo仿真在高负载时,虚拟机里的图形渲染和传感器计算会掉帧,导致仿真数据不对,你以为是代码的问题,实际是虚拟化层拖了后腿。
- 串口和网卡:某些飞控开发板通过以太网连接(比如树莓派作为机载计算机),虚拟机的网络桥接模式偶尔会出现丢包,查起来非常费劲。
当然,如果你只是先体验一下Linux、熟悉常用命令,那虚拟机完全够了。我的建议是:第一步用虚拟机学习基础知识,一旦决定深入无人机开发,立即转换到双系统。我自己就是这么过来的——先用VMware看了一个礼拜的Linux基础,然后忍痛分区装了双系统。
2.2 双系统安装实操细节与避坑
安装Ubuntu 20.04的过程本身不复杂,但有几个细节直接关系到后面的使用体验。
启动盘制作:推荐使用Rufus(Windows下)或者balenaEtcher(跨平台)来制作启动U盘。这里有个坑:制作时分区类型要选GPT,目标系统类型选UEFI,否则在一些较新的笔记本上会无法引导启动。老一点的电脑如果只支持Legacy BIOS,才选MBR。
磁盘分区:新手最容易在这个环节栽跟头。我的建议是,在Windows里先用“磁盘管理”压缩出一个空闲分区,不要删分区、不要格式化。然后在Ubuntu安装界面选择“Something else”,手动挂载:
/根分区:分配50GB以上(如果你要编译PX4、跑Gazebo仿真,建议80GB起步)swap交换分区:分配电脑内存大小即可,比如16GB内存就分16GB/home分区:把剩余空间都给它,以后源码、下载、项目文件都在这
这里特别提醒:/home分区不要和/分区合并到一起。因为一旦系统出问题需要重装,只要/分区格式化,/home里的数据都能保留。我做项目这么多年,这招帮我保住了好几次没备份的源码。
软件源替换:装完系统第一件事就是换源,否则下载软件包的速度会让你抓狂。Ubuntu 20.04的源配置文件在/etc/apt/sources.list,用清华源或者阿里云源都行。我用的是清华源,实测速度稳定。替换完记得执行:
sudo apt update sudo apt upgrade -y2.3 基础开发环境初始化脚本
装完系统、换完源,接下来就是安装无人机开发的基础工具包。下面这段是我每次给新机器初始化都在用的命令集合:
# 基础编译工具链 sudo apt install -y build-essential cmake git vim # Python 3开发环境 sudo apt install -y python3 python3-dev python3-pip # 串口和USB工具 sudo apt install -y putty minicom screen # 其他常用工具 sudo apt install -y net-tools curl wget htop # 图形界面辅助 sudo apt install -y terminator这些工具看着基础,但每一个都有用:build-essential是后续编译任何C/C++项目的地基;cmake是PX4这类大型项目的构建系统核心;git是版本管理命脉;minicom和screen用于串口调试飞控日志。
装完这些,建议把系统重启一遍,让驱动和内核模块都正常加载再继续。
3. Linux工程基础:命令行与文件系统的无人机场景化运用
3.1 文件权限模型:无人机项目里最常踩的坑之一
Linux的文件权限模型(读r、写w、执行x)几乎是每个新手遇到的第一堵墙。在Windows里你双击就能运行程序,在Linux里不行——你要么给文件加执行权限,要么就要报Permission denied错误。
无人机项目里最典型的一个场景:你下载了飞控固件的编译脚本install.sh,然后执行./install.sh,结果系统提示权限不够。原因就是该文件没有执行权限。解决办法:
chmod +x install.sh ./install.sh还有串口设备权限问题。飞控通过USB连接到电脑,在Linux里对应的设备名一般是/dev/ttyUSB0或/dev/ttyACM0,默认只有root用户和dialout组的用户才能访问。损坏设备权限最常用的方法:
sudo usermod -a -G dialout $USER修改完后一定要注销重新登录,用户组才会生效。这个步骤我在课堂上反复强调,因为几乎每届都有学生在这一步卡住,然后问我“为什么加了dialout组还是没权限”——答案就是你还没重新登录。
3.2 命令行实操:无人机开发中最高频的命令清单
在无人机项目里,有些命令出现的频率高到离谱,我把它们分成了几类,每一类都对应一个实际场景:
| 命令 | 场景说明 |
|---|---|
lsusb | 查看USB设备是否被系统识别。飞控插上没反应,第一件事就是lsusb看设备列表 |
dmesg | tail -20 | 查看内核日志。USB设备插入时内核会打印识别信息,是排查驱动问题的关键 |
ls /dev/ttyUSB* | 查看串口设备节点是否生成 |
chmod 777 /dev/ttyUSB0 | 临时给串口设备权限(不推荐长期用,调试时方便) |
df -h | 查磁盘空间。编译PX4经常要几十GB,磁盘满了会报莫名其妙的神秘错误 |
free -h | 查内存使用情况,Gazebo仿真崩了先看内存够不够 |
top/htop | 实时看CPU、内存占用,排查机载程序性能瓶颈 |
还有一个比较有意思的是rsync命令,很多做无人机的人都用它把代码同步到机载计算机(比如树莓派、NVIDIA Jetson)上。局域网内的同步整个项目代码:
rsync -avz --progress ./project_dir/ user@192.168.1.100:/home/user/project/我觉得命令行不要求全背,但要达到“看一遍就理解,遇到问题知道去哪查”的程度。真正常用的命令就那二三十个,多敲几遍自然就熟了。
3.3 压缩解压与文件传输的工程应用
无人机项目里经常要从网上下载工具链、固件源码,跟你打交道最多的压缩格式就是.tar.gz、.tar.bz2、.zip。这里有一个关键区别:
.zip:Windows最常用,Linux下用unzip file.zip解压.tar.gz:Linux最常见,一条命令搞定:tar -zxvf file.tar.gz.tar.bz2:压缩率更高但速度慢,飞控源码包偶尔见到:tar -jxvf file.tar.bz2
最让我印象深刻的是PX4源码下载,它默认通过Git仓库克隆,第一次下载可能就要好几个GB。如果直接git clone速度很慢,建议加上--recurse-submodules参数并提前配好代理镜像(这是后面第6章会详细讲的内容)。总之,掌握基本的压缩解压命令能让你在处理源码包时不被劝退。
4. 交叉编译与开发工具链:无人机项目专属的“硬核”知识
4.1 交叉编译到底是什么:一个接地气的类比
交叉编译这个概念,我每次都要费很大劲才能让新手弄明白。其实用一个类比就能说清楚:
你在Mac上写了一个APP,想装到华为手机上运行。Mac和手机的CPU指令集不一样,你不能把Mac上编译出来的程序直接拷贝到手机上。你需要在Mac上安装一个“华为手机视角的编译器”,让它生成手机能跑的程序,这个过程就是交叉编译。
对应到无人机开发:你在PC的x86架构上编写代码,但飞控板通常是ARM架构(比如STM32),PC直接编译出来的程序飞控跑不了。你需要用交叉编译工具链,让PC生成ARM架构的机器码,然后烧录到飞控上。
无人机行业里最常见的交叉编译场景有:
- PX4固件交叉编译:PX4在PC上编译时会自动调用
arm-none-eabi-开头的GCC工具链,为STM32 F系列芯片生成固件。 - 机载计算机程序:如果你在树莓派或Jetson上跑视觉算法,就需要在PC上安装对应的交叉编译器,或者直接在ARM主板上本地编译。
- Linux内核/驱动模块:如果给飞控定制内核模块,同样需要交叉编译环境。
4.2 从零安装PX4 Ubuntu 20.04开发环境
PX4官方提供了一键安装脚本ubuntu.sh,但它会把一大堆依赖都装到系统里,耗时很长。我实际项目里更推荐按需安装,核心依赖分三大块:
第一块:基础编译工具
sudo apt install -y \ git zip qtcreator cmake \ build-essential genromfs ninja-build exiftool \ astyle cmake-format第二块:Python依赖与pip包
sudo apt install -y python3-pip python3-setuptools python3-dev pip3 install --user \ pyserial empy pyros-genmsg packaging \ jinja2 numpy toml这里有个坑:empy这个Python模板库,PX4编译时必须用3.3.2版本,如果装成新版会导致固件编译报错。指定安装:
pip3 install --user empy==3.3.2第三块:交叉编译器
sudo apt install -y gcc-arm-none-eabi gdb-multiarch装完可以用这个命令验证交叉编译器是否正常,看到“arm-none-eabi-gcc”版本信息就说明OK:
arm-none-eabi-gcc --version4.3 编译工具链中的关键参数与选择逻辑
在PX4编译过程中,有个重要概念叫“构建目标(build target)”,它决定了你编译出来的固件要烧到哪块飞控板上。最常用的几个目标:
| 构建目标 | 适用硬件 | 说明 |
|---|---|---|
px4_fmu-v5 | Pixhawk 4 / FMUv5 | 最常见的Pixhawk系列板卡 |
px4_fmu-v6x | Pixhawk 6系列 | 新硬件,性能更强 |
sitl | 无硬件(纯仿真) | 在PC上跑软件在环仿真,不需要真机 |
px4_fmu-v2 | Pixhawk 1代 | 老硬件,已逐渐淘汰 |
编译命令是这样:
make px4_fmu-v5如果你只想快速验证代码语法对不对,不烧真机,那就编译仿真版:
make sitl gazebo-classic这个命令会启动Gazebo仿真器,同时编译PX4软件在环仿真固件。我强烈建议新手上路先跑仿真,仿真里炸机不心疼,真机上炸机修飞机钱包心疼。
5. 开发环境必备工具:Git、编辑器与调试工具的工程级配置
5.1 写代码环境:VS Code还是Vim
无人机项目里写代码,我用的是VS Code,飞控代码用VS Code里的Remote-SSH插件直接编辑机载计算机上的文件,非常方便。插件方面必备这几个:
- C/C++:微软官方插件,提供语法高亮、智能提示、调试支持
- CMake Tools:CMake工程构建一体的IDE化支持
- Python:写地面站脚本、数据处理时要用
- GitLens:Git历史可视化管理,排查“谁改了我的代码”特别有用
- Remote-SSH:远程开发机载计算机
但我也认识一些老手坚持用Vim,说“在无图形界面的服务器上工作只能靠Vim”。Vim的上手曲线有点陡峭,我建议新手先把基础的打开文件、编辑、保存、退出记住就行:
vim filename.py # 打开文件 i # 进入插入模式(可以输字符) Esc # 退出插入模式 :wq # 保存并退出 :q! # 不保存强制退出5.2 Git版本管理:无人机项目里必须养成的肌肉记忆
无人机软件项目动辄几百个源文件,没有Git管理代码,你很难知道改了什么、要不要回滚。真实项目中我最常规避的一个场景是:在机载计算机上直接改代码,改坏了想恢复,却发现没有提交任何版本。到这一步只能手动翻历史记录,痛苦无比。
Git的最核心流程其实就几条命令:
git init # 仓库初始化 git add . # 把所有文件加入暂存区 git commit -m "提交信息" # 提交到本地仓库 git log --oneline # 查看提交历史 git checkout -- filename # 丢弃工作区某个文件的修改 git branch feature/test # 新建分支 git checkout feature/test # 切换到新分支对于PX4这种大型项目,我强烈建议不要直接在主分支上乱改代码,而是从官方版本拉出自己项目的分支,这样以后官方更新时还能合并回来。
git clone --recurse-submodules https://github.com/PX4/PX4-Autopilot.git cd PX4-Autopilot git checkout -b myproject v1.13.3这里为什么用--recurse-submodules参数?因为PX4本身依赖了几十个子模块(比如固件框架、驱动库),不加上这个参数克隆下来的源码不完整,编译必失败。
5.3 串口调试与日志查看:地面站之外的“单手工具”
地面站功能很多,但有时候你只需要快速看一眼飞控输出的日志,或者跟传感器模块手动通信测试,这时命令行工具反而更高效。
minicom:老牌串口终端,我用的最多:
sudo minicom -D /dev/ttyUSB0 -b 115200-D指定串口设备,-b指定波特率。飞控的调试串口通常是57600或115200,具体参数要查你的飞控硬件手册。screen:退出方式比minicom方便(Ctrl+A然后按K),临时看数据很方便:
screen /dev/ttyUSB0 115200QGroundControl:图形化地面站,除了调参还能刷固件、看实时日志。不属于命令行工具,但它是无人机地面站的事实标准,装机时顺便装了准没错。
6. 环境问题排查:那些能把人逼疯的典型场景
6.1 下载慢、克隆失败的根源与解决
无人机开发里,你打交道最多的“外网资源”就是GitHub(PX4源码、硬件驱动库都在这)。国内裸连GitHub经常只有几十KB/s,甚至直接超时。很多新手在这步浪费了大量时间。
我的处理方案是给Git配置一个代理(如果你本地有代理服务的话):
git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy http://127.0.0.1:7890如果不想用代理,也可以用一些GitHub镜像加速方式(GitHub Proxy、FastGit等)。但最稳妥的还是在编译脚本层面解决问题:提前把PX4源码包里的大子模块下载好,或者用gitee上别人同步的镜像仓库拉取。
等基础环境装好后,如果你的开发任务不依赖频繁访问GitHub,可以考虑把代理关掉省点流量:
git config --global --unset http.proxy git config --global --unset https.proxy6.2 串口无法识别飞控:三步排查法
飞控插上电脑后,QGroundControl显示“No device connected”,这种情况在Linux下非常常见。我归纳了一个三步排查法:
第一步:检查设备有没有被系统发现
lsusb如果看到类似“STMicroelectronics STM32”或“PX4 FMU”的条目,说明USB层面识别到了。什么USB信息都没有,换个线、换一个USB接口再试,很多问题的根源只是USB线质量差。
第二步:检查串口设备节点有没有生成
ls /dev/ttyUSB* /dev/ttyACM*PX4飞控一般生成ttyACM0,ArduPilot也差不多。没有设备节点就是驱动问题,Ubuntu 20.04对常见USB转串口芯片(FTDI、CH340、CP2102)都内置了驱动,一般不需要额外装驱动。
第三步:检查当前用户有没有权限
ls -l /dev/ttyACM0看第一列权限位和所属组,如果组名是dialout,而你还没加进去,就执行我前面讲的usermod命令。
6.3 编译报错的三大“坑王”与其解法
在做PX4编译时,有几个报错出现的频率极高,我把它们总结成了一张避坑表:
| 报错特征 | 根本原因 | 解决办法 |
|---|---|---|
empy: command not found | Python模板库没装或版本不对 | pip3 install empy==3.3.2 |
gcc-arm-none-eabi: No such file or directory | 交叉编译器缺失 | sudo apt install gcc-arm-none-eabi |
ModuleNotFoundError: No module named 'em' | Python环境里缺少em模块 | pip3 install pyros-genmsg |
基本上90%的编译失败都不是代码问题,而是依赖环境没配对。这也是我前期不厌其烦强调“一定要跟着官方推荐的Ubuntu版本走”的原因。
6.4 系统崩溃后的快速恢复策略
做嵌入式开发,系统越用越乱的概率很高。为了防止系统崩溃后个人配置和源码全丢,我给自己定了一个规则:/home目录里的代码和配置全部用Git跟踪,重要笔记同步到云盘,系统出问题直接格盘重装,恢复时间控制在两小时内。
具体来说,我会把自己习惯的dotfiles(比如.bashrc、.vimrc、.gitconfig)放在一个单独的Git仓库里,新机器上直接克隆然后软链接到home目录。这样无论换电脑还是重装系统,都能快速恢复熟悉的工作环境。
7. 常用Linux工程命令速查手册(无人机开发精简版)
7.1 文件与目录操作
pwd # 当前路径 ls -lah # 列出当前目录所有文件及其权限和大小 cd /home/user/project # 切换目录 mkdir -p src/include # 递归创建多级目录 cp -r old_dir new_dir # 递归复制目录 mv old_name new_name # 重命名或移动 rm -rf temp_dir # 强制删除目录(非常危险,慎用)7.2 系统与进程管理
df -h # 磁盘空间 free -h # 内存占用 ps aux | grep px4 # 查找PX4相关进程 kill -9 PID # 强制终止进程 systemctl status ssh # 查看SSH服务状态 sudo systemctl enable ssh # 设置SSH开机自启7.3 网络调试命令
ifconfig # 查看本机IP地址 ping 192.168.1.1 # 测试局域网连通性 ssh user@192.168.1.100 # SSH远程登录机载计算机 scp file.zip user@192.168.1.100:/tmp/ # 复制文件到远程主机 ss -tunap # 查看端口监听情况7.4 权限与用户管理
sudo chown -R user:user /home/user/project # 递归修改文件属主 sudo chmod -R u+rwX,g+rX,o+rX /home/user/project # 设定标准权限 groups # 查看当前用户属于哪些组这些命令不需要背,但最好在虚拟机里都敲一遍,形成肌肉记忆。真到了做项目的时候,这些是最基础的“地基工具”。
8. 后续学习路线与个人经验谈
如果你把前面这些环境全部搭建完成,并且能用命令行做基本的文件操作、权限配置、软件安装、Git管理、交叉编译,那就意味着你已经具备了无人机软件开发最核心的“生存技能”。
接下来我建议的学习路线是这样的:
第一阶段(1~2周):每天花半小时刷Linux常用命令,重点练文件操作、权限、压缩解压、进程管理。目标是看到一个需求就知道该用什么命令、去哪里查帮助。
第二阶段(2~4周):把PX4官方源码克隆下来,尝试编译sitl仿真目标,体验完整的编译过程。遇到报错不要慌,先看报错信息,再根据信息搜索解决方案。
第三阶段(1~2个月):在Gazebo仿真环境里跑一架多旋翼飞机,学会用QGroundControl连接仿真飞机、查看日志、修改参数。从仿真到真机之前,把USB权限、串口调试、固件烧录流程全部走通。
第四阶段:开始读PX4代码结构,理解uORB通信机制(这是PX4模块之间通信的核心)、模块注册方式、参数系统。再往深走就是写自己的飞行控制模块,这就正式踏入无人机软件开发的大门了。
最后分享一点个人体会:我在带新人时发现,真正能快速上手的,往往不是那些“什么都会一点”的人,而是遇到问题知道怎么独立排查的人。无人机开发的环境问题千奇百怪,今天可能是USB掉驱动,明天可能是编译缓存冲突,后天可能是Python依赖版本不对。你不能每次都指望别人帮你解决,必须有“我自己能搞定”的信心。而这份信心,就来自你把上面这些基础操作都亲手敲过一遍之后,对环境越来越熟悉的那种掌控感。到了那个阶段,无人机软件开发对你来说就不再是“处处是坑”,而只是“按照流程一步步推进”的日常工作了。