
做无人机软件开发的很多人第一个门槛不在算法也不在代码逻辑而在环境搭建。我见过不少同学拿到一台机载电脑第一反应是装Windows结果折腾半天发现PX4编译工具链、ROS、MAVSDK这些在Linux下才是主力支持Windows要么缺依赖、要么驱动不认最后还得老老实实回到Ubuntu。Module 3这门课恰好就是解决这个问题的用Ubuntu 20.04 Linux工程基础把开发环境彻底搭稳后面跑仿真、编固件、调参才不会处处受制。这篇文章我把整个环境搭建过程、踩坑点和常用工程命令完整梳理一遍。不光是让你装个系统而是带你搞清楚为什么要这样配置、哪些命令是无人机开发中的高频操作、出了问题怎么排查。适合刚入门无人机软件方向、准备在Jetson或x86工控机上跑代码的人也适合那些已经装好系统但总觉得环境别扭、想系统性整理一遍的同学。1. 为什么无人机开发绕不开 Ubuntu 20.04很多人会问现在Ubuntu都出到24.x了为什么无人机课程里还在用20.04这个问题问得好答案不是“老师懒得更新”而是无人机软件生态真的被20.04“绑定”了。1.1 LTS长期支持与ROS生态的绑定关系Ubuntu 20.04属于LTS版本官方支持周期到2025年之后还有扩展维护。对开发者来说稳定性比版本号新更重要。你装在机载电脑上的环境可能一跑就是半年一年如果系统隔三差五更新出问题那飞控代码还没跑起来光修系统就够你喝一壶。更关键的是ROS 2的发行版对应关系。20.04对应的ROS 2发行版是Foxy Fitzroy这也是目前大量无人机、机器人教学和开源项目默认的版本。很多基于ROS 2的仿真环境、SLAM方案、路径规划算法作者就是在Foxy上开发的你换到新版本可能源码能编过但某些依赖库版本对不上卡你两三天都正常。还有一个现实因素很多飞控开发工具链、NVIDIA Jetson的官方镜像、MAVSDK的预编译包都明确支持Ubuntu 18.04或20.04。你说你想用22.04结果刷完镜像发现CUDA版本、OpenCV版本都得重新配那纯属给自己加戏。1.2 底层硬件适配从NVIDIA到ARM板卡无人机机载电脑目前主流就三类x86工控机、NVIDIA Jetson系列NX、Nano、AGX、还有部分ARM开发板。Jetson官方推荐的Ubuntu版本长期停留在18.04和20.04因为NVIDIA的驱动、CUDA、TensorRT这些底层库都是跟着LTS版本走的。我自己实测过同一套Jetson Orin NX刷20.04的官方镜像开机之后nvidia-smi直接识别驱动CUDA装好就能用换成22.04非官方镜像虽然系统能起来但总线、风扇控制、电源管理这些细节经常有兼容问题查起来非常难受。做无人机至少要保证底层能稳定跑所以20.04不是情怀是省时间。再说驱动。NVIDIA 520这类版本的Linux驱动在20.04下安装最顺因为Ubuntu的显卡驱动PPA和内核版本匹配度好。你在20.04上跑深度学习推理用预编译的PyTorch、TensorRT轮子基本不用自己从源码编换个系统版本可能连pip install都开始报“找不到匹配版本”那时候你就知道20.04香在哪了。2. 从镜像到开机环境初始化与换源实操环境搭建的第一步不是敲命令而是把系统干净、完整地装好。这一步不少同学图省事随便找镜像或者装完就更新结果后面各种隐患。我建议按下面的流程来。2.1 镜像下载、校验与启动盘制作先强调一个习惯不要从乱七八糟的网站下系统镜像。Ubuntu官方镜像速度可能慢但你完全可以用清华大学开源软件镜像站、阿里云镜像站下载。网址很直观进Ubuntu目录选择20.04的iso文件就行。下载完之后我强烈建议校验一下SHA256。你可能会觉得多此一举但镜像文件大下载过程中可能损坏如果直接拿来装系统装到一半报错更浪费时间。Linux下用sha256sum命令Windows下可以用PowerShell的Get-FileHash。sha256sum ubuntu-20.04.6-desktop-amd64.iso启动盘制作Windows上推荐用RufusLinux下可以直接用dd命令。U盘容量不用太大8G就够。注意dd命令会清空U盘所有数据别写错设备名。sudo dd ifubuntu-20.04.6-desktop-amd64.iso of/dev/sdX bs4M statusprogress sync2.2 分区方案与双系统避坑如果你准备用一台电脑装双系统务必先搞清楚你的磁盘格式和引导方式。现在多数电脑是UEFI引导Windows已经占用了ESP分区Ubuntu安装器一般会自动识别但偶尔会出现引导项丢失的情况建议提前准备一个Boot Repair U盘备用。分区方案上我给开发机的建议很简单一个大ext4分区挂载根目录一个swap分区如果磁盘充足再单独分一个/home。别分太碎什么/var、/tmp单独分区很容易把空间写满又不好扩展。对无人机开发来说你通常还会装ROS、深度学习库、仿真软件这些动辄几十GB建议根目录至少预留100GB。有人问要不要把Windows彻底删掉、单跑Linux。如果你只做无人机软件开发完全可行但如果你还要用到Windows环境下的飞控地面站、模拟器或者串口工具建议保留双系统省得后面又想办法搞虚拟机。这里要提醒一句装完双系统后最好先在Windows里关闭快速启动否则Linux下挂载NTFS分区经常会提示文件系统不一致。2.3 apt源切换与update/upgrade的区别系统装完后第一件事不是装Python、装IDE而是换apt软件源。默认源在国外下载速度可能让你怀疑人生。我一般直接用清华源把/etc/apt/sources.list里的archive.ubuntu.com和security.ubuntu.com替换成mirrors.tuna.tsinghua.edu.cn。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这里要特别讲一下update和upgrade的区别。这个问题被问过太多次了。apt update是更新软件源列表让系统知道有哪些软件包的新版本可用它不会装任何新东西apt upgrade才是真正把已安装软件升级到新版本。日常操作建议先update再upgrade两个命令连着敲没问题。但刚装完系统那天我不建议立刻upgrade尤其不要升级内核。先确认一下常用硬件驱动都正常再决定要不要整体升级否则内核一换NVIDIA驱动可能要跟着重装。3. Linux工程基础把命令用成肌肉记忆无人机开发的工作流和普通软件开发不太一样。你可能要SSH登录机载电脑、用scp传固件、在终端里编译ROS工作空间、用串口连接飞控、看日志文件、处理传感器数据。这些操作都离不开Linux命令。我把实际开发中最常用、也最容易被卡住的部分整理出来。3.1 高频命令与项目目录管理先给一份我日常工作里出镜率最高的命令清单。这些不是让你死记硬背而是每个都要知道在什么场景下用。命令典型使用场景补充说明ls / ll / tree查看目录结构ll是ls -al的别名开发中更常用cd / pwd切换目录、确认位置建议把cd和绝对路径结合在一起用cp / mv / rm文件复制、移动、删除rm -rf要慎用建议先ls确认目标cat / less / tail -f查看文件、实时看日志tail -f在调试无人机日志时非常好用grep / find搜索文件内容和文件名配合管道符可以快速定位代码chmod / chown修改权限和属主串口设备访问经常需要用到df -h / du -sh查看磁盘空间和目录大小排查磁盘满、清理日志时必备ps / top / htop查看进程和系统负载无人机机上程序异常退出时先看这里tar / unzip解压压缩包注意中文文件名乱码问题举个例子你从网上下了一个数据集或代码包需要解压到指定目录并确认大小。很多人直接右键提取但放到服务器或机载电脑上没有图形界面这些命令就是唯一工具。mkdir -p ~/project/data tar -zxvf dataset.tar.gz -C ~/project/data/ du -sh ~/project/data3.2 权限模型与串口设备Linux的权限模型跟Windows不一样不是“管理员”和“普通用户”两个概念而是文件所有者、所属组、其他用户三组权限。每组权限又分为r、w、x。你用ls -l看到的第一个字段比如-rw-r--r--就是这种权限的表达。无人机开发中最典型的权限问题是访问串口。飞控、GPS、数传模块往往通过USB转串口设备接入设备文件通常叫/dev/ttyUSB0、/dev/ttyACM0。默认情况下当前用户没有权限打开它你需要在启动时手动授权或者把用户加入dialout组。sudo usermod -aG dialout $USER这个命令执行完要重新登录才会生效。加组的意义是让普通用户也能访问串口设备否则每次都要sudo很多软件里会报错或者找不到设备。之后你可以在终端里用ls -l /dev/ttyUSB0确认权限然后写个Python脚本测试一下。python3 -c import serial; sserial.Serial(/dev/ttyUSB0, 115200); print(s.name)权限这块还有一个常见坑你明明加了dialout组结果还是Permession denied很可能是你当前终端还没重新加载组信息。用newgrp dialout或者退出重新登录可以解决。3.3 sed和文本处理的一个实战案例很多初学者觉得sed、awk这类命令是“老古董”但在无人机开发里它们非常实用。举一个我自己遇到的场景飞控日志里有很多带时间戳的字段我想批量把文件里的某个参数改掉或者从一大段编译日志里提取错误信息。在图形化编辑器里手动改几十个文件太痛苦sed一条命令就完事。sed -i s/old_param/new_param/g config/*.yamlsed还有一个典型用法是删除文件里的空行、查看指定行范围。比如你编译日志有几千行只看前30行确认开头信息sed -n 1,30p build.logawk则适合处理按列排列的数据。比如你需要提取某个CSV文件的第二列和第五列生成新的文件给绘图脚本用awk -F , {print $2, $5} sensor_data.csv extract.txt这类命令确实需要花点时间练但一旦用熟处理日志、批量改配置的效率会高出一大截。3.4 用shell脚本串联日常构建刚开始做项目时你可能每天重复敲同一串命令激活环境、编译、开仿真、跑测试。我建议把这些动作整理成shell脚本放到项目里统一管理。别小看这一步它能帮你减少很多低级失误。下面是一个无人机软件开发中非常典型的构建脚本假设你有ROS 2的工作空间和MAVSDK库#!/bin/bash set -e source /opt/ros/foxy/setup.bash cd ~/ros2_ws colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPERelease source install/setup.bash ros2 launch drone_bringup simulation.launch.py这个脚本里有几个关键点要说明set -e表示任何命令执行失败就立刻退出避免你在错误的路线上继续往下跑每次编译前先source ROS环境保证能找到ros2命令colcon build加--symlink-install是ROS 2开发时的推荐做法Python代码改动后不需要重新编译直接生效调试效率高很多。写脚本的时候我吃过一个亏就是没有加set -e结果前一个命令编译失败脚本还在继续启动了旧版本的程序排查了半天才发现是缓存问题。现在我做任何自动化脚本都会把set -e带上。4. 开发语言与工具链Python虚拟环境与ROS基础无人机软件开发的核心语言基本就是Python和C。C用于飞控底层、实时控制Python用于算法验证、数据处理、AI推理、脚本工具。一个刚接触这个方向的人我建议先别急着搞C把Python环境和工具链调理顺至少能跑通大部分仿真和算法。4.1 管理Python版本别动系统PythonUbuntu 20.04自带的Python是3.8很多第三方库的老版本都支持这点比新系统省心。但有个铁律不要随意改系统自带的Python更不要用pip install直接往系统Python里装包因为很多系统工具依赖Python你把包的版本一换可能导致整个系统异常。实际开发中我推荐用pyenv或者conda管理独立Python版本。我的常用配置是pyenv venv轻量灵活也有不少做深度学习的朋友习惯用Anaconda它更重但包管理方便二者看个人喜好。# 安装pyenv后安装Python 3.8.10 pyenv install 3.8.10 mkdir -p ~/uav_project cd ~/uav_project pyenv local 3.8.10 python3 -m venv venv source venv/bin/activate这样创建的虚拟环境跟系统Python隔离你想装什么包、怎么折腾都不会搞坏全局环境。而且每个项目一个环境不会出现“这个项目需要的numpy版本和那个项目冲突”的情况。4.2 虚拟环境与依赖隔离的实际用法很多人问为什么一定要用虚拟环境直接pip install不行吗我举个例子。项目A要用numpy 1.19因为要兼容TensorRT项目B用最新numpy才能跑数据处理脚本。如果你不隔离装完B再把A的环境破坏掉可能连MAVSDK的Python绑定都导入失败。这种问题排查起来特别闹心因为报错往往藏在依赖链深处。所以建议每个项目都做requirements.txt把依赖固定下来。pip freeze requirements.txt换环境时直接pip install -r requirements.txt如果你在离线环境工作比如机载电脑没有外网还能提前在下载好wheel包离线安装。这个在无人机项目里很常见因为飞行测试场地经常没网。做法是在有网电脑上用pip download把依赖下载到一个目录再拷贝到目标机器用pip install --no-index --find-links安装。4.3 编译工具、离线安装与ROS工作空间做无人机开发光是Python还不够。你可能要自己编译C代码、编译飞控固件、编译ROS功能包。这些统称为工具链缺一不可。Ubuntu 20.04下最基础的编译工具是build-essential它包含gcc、g、make等。sudo apt install build-essential cmake git如果你要做ROS 2开发建议按官方文档安装但有一个重点把系统源换成国内镜像后ROS源也要换成对应的国内镜像否则安装速度会非常感人。ROS 2的工作空间结构要理解清楚src放源码build放编译中间文件install放安装产物log放日志。更新代码后有时候会出现“改动没生效”的情况多半是没重新编译或者编译后忘了source install/setup.bash。离线安装是无人机开发里比较高频的场景。比如你在实验室编译好了程序要部署到机载电脑上但机载电脑没网。最简单的做法是依赖打包pip download -r requirements.txt -d ./offline_packages然后拷到目标机器上pip install --no-index --find-links./offline_packages -r requirements.txt4.4 无人机软件栈中的ROS与MAVSDK在无人机软件栈里ROS不是必须的但如果你做自主飞行、编队、视觉导航这类复杂任务ROS几乎是标配。ROS负责节点通信、话题发布订阅、参数管理MAVSDK负责跟PX4飞控通信把飞控的实时状态、位置信息、姿态信息传给上层程序同时支持发送起飞、降落、航点任务等指令。一个典型的最小系统是PX4飞控通过串口连接到机载电脑机载电脑上跑MAVSDK-Python或者MAVROS节点再往上挂自己的视觉SLAM节点或路径规划节点。所有节点间用ROS话题通信。我第一次搭这套环境时最容易出问题的是串口通信。PX4用USB连到机载电脑默认设备是/dev/ttyACM0但程序可能找不到设备。建议先确认一下设备名再配置MAVSDK的connection_url否则你会看到程序一直重连却连不上。import asyncio from mavsdk import System async def run(): drone System() await drone.connect(system_addressserial:///dev/ttyACM0:115200) async for state in drone.core.connection_state(): if state.is_connected: print(connected) break asyncio.run(run())5. 显卡驱动、显示服务器与Jetson设备调试这一部分看起来比较偏向桌面工作站但在无人机地面站、仿真环境、深度学习推理场景里却非常关键。你不可能在没图形界面的终端里跑Gazebo仿真也不会想在没NVIDIA加速的环境里训练目标检测模型。所以显卡驱动和显示服务器的问题必须处理好。5.1 NVIDIA驱动安装的两种路径Ubuntu下装NVIDIA驱动有几种方式我推荐两条路线一条是Ubuntu自带的“附加驱动”图形界面安装适合新手另一条是命令行用显卡驱动PPA安装适合远程操作或者图形界面出问题时使用。先看当前显卡和驱动状态lspci | grep -i nvidia nvidia-smi如果nvidia-smi能输出显卡信息说明驱动已经就绪。如果提示没有驱动优先用PPA方式安装sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt update sudo apt install nvidia-driver-520安装完驱动后重启。这个阶段最容易出问题的是“安装后黑屏”或“卡在登录界面”。这往往是因为内核模块没有正常加载或者系统仍然默认走nouveau开源驱动。遇到这种情况可以尝试进入recovery模式在grub启动项里加nomodeset参数或者在安装驱动前就把nouveau禁用掉。禁用方法是在/etc/modprobe.d/blacklist-nvidia-nouveau.conf里加两行然后执行sudo update-initramfs -u更新。5.2 Wayland与X11遇到的实际问题Ubuntu 20.04桌面版默认用的是Xorg但也支持Wayland。不少开发者在网上查资料会看到关于Wayland和X11的讨论但你知道自己的图形会话用的哪个吗查看方式很简单echo $XDG_SESSION_TYPE这个输出如果是x11就说明在Xorg下运行如果是wayland就说明在用Wayland。对无人机开发来说我建议日常就用Xorg。原因很实在很多远程桌面工具、窗口管理器、ROS可视化工具比如rqt、Rviz在Wayland下会有兼容问题表现包括画面撕裂、鼠标指针错位、窗口无法拖动。我在实际项目里就遇到过用Wayland启动Gazebo后鼠标无法拖动物体换成X11一切正常。切换方法在登录界面选择用户后点击密码框旁边的齿轮图标选择“Ubuntu on Xorg”再登录。如果你是通过GDM配置修改也可以编辑/etc/gdm3/custom.conf但一般不需要。5.3 Jetson平台的特殊处理Jetson平台不能直接使用x86版的NVIDIA驱动安装包它需要JetPack SDK提供的驱动和库。所以如果你用的是Jetson想装驱动正确做法是到NVIDIA官网下载对应JetPack版本的镜像然后按照官方文档烧录。烧录过程中建议给系统预留足够大的根目录空间因为JetPack自带CUDA、cuDNN、TensorRT体积非常大。在Jetson上开发还有个常见问题风扇策略。默认散热策略可能偏保守跑算法时机身很热但风扇转速起不来。可以安装jetson-stats工具用sudo apt install python3-jetson-stats然后用jtop查看和控制风扇转速、功率模式。开发时可先切到最大性能模式测试完再切回平衡模式延长电池续航。sudo nvpmodel -m 0 # 最大化性能 sudo jetson_clocks # 锁定CPU/GPU频率注意长期用最大性能模式会让模块温度偏高建议仅在性能测试时使用。6. 常见问题速查与排查思路环境搭建这件事90%的时间其实在排查问题。我把这几个月里被问过最多、也最折磨人的几个问题汇总成一个排查清单方便你直接对照。6.1 双系统引导、磁盘空间与WSL的选择双系统装完后开机直接进Windows没有引导菜单这是UEFI模式下的常见问题。我建议先在BIOS里检查启动顺序把UEFI引导放在最前面如果还不出现Grub菜单用Boot Repair工具修复。修复命令sudo add-apt-repository ppa:yannubuntu/boot-repair sudo apt update sudo apt install boot-repair boot-repair磁盘空间不够是另一个高频问题。Ubuntu下查看磁盘使用情况用df -h定位大文件用du -sh配合路径。如果你想删掉一些日志或缓存但删完之后发现磁盘空间没释放多半是有进程还在占用那些文件。尤其是删除正在被程序使用的日志文件空间要等进程关闭才释放。用lsof可以查出来lsof | grep deleted找到对应进程后重启它空间就会回来。这个技巧在我处理机载电脑日志爆炸时帮过不少忙。如果你在考虑用WSL做无人机开发我明确说一句WSL适合测试代码逻辑不适合直接操作真实飞控硬件。它对串口、USB设备的透传支持虽然有但延迟和稳定性不够好也不适合需要图形加速的Gazebo仿真。如果只是验证一个算法思路、编译一个纯软件模块WSL完全够用但一旦涉及硬件或完整仿真老老实实用原生Linux或者虚拟机。6.2 解压乱码、外接显示器无画面、虚拟机问题中文文件名的压缩包在Linux下解压经常乱码很多人以为是系统字体问题其实根源是压缩包里的文件名编码是GBK而Linux默认用UTF-8。解决办法是用unzip的-O参数指定编码unzip -O CP936 中文文件包.zip如果你的unzip版本不支持-O参数可以考虑装p7zip-full后再用7z解压兼容性好很多。这个细节在团队协作中很实用你从微信或者网盘收到同事发的压缩包不会因为乱码而浪费一下午。外接显示器在Linux下无画面先别急着重装驱动。检查一下显示接口优先用DP口或HDMI直连不要经过扩展坞然后在系统设置里看显示器是否被识别为“unknown display”。如果识别了但没画面切换一下显示服务器X11和Wayland之间的表现往往不同。还不行就看看显卡驱动是否有警告journalctl -xe里会给出关键线索。虚拟机安装Linux蓝屏的问题大多数是因为虚拟机里没有开启CPU虚拟化功能或者给虚拟机分配的显存太小。去BIOS里确认Intel VT-x或AMD-V已经打开然后把虚拟机内存给到至少4GB。如果你只是临时测试一下某个命令的效果用虚拟机完全没问题但如果你要做传感器数据处理、跑实时控制物理机上双系统或者单Ubuntu体验会好得多。6.3 我踩过的三个环境坑这里说几个我实际踩过的坑都是那种“不致命但很耽误事”的类型。第一个是系统Python被污染。有一阵子我图省事直接给系统Python装了很多pip包后来某个依赖依赖冲突导致Ubuntu的软件中心、桌面组件全部出问题最后只能重装系统。后来我所有项目一律用虚拟环境再也不碰系统Python这个问题彻底消失。第二个是ROS编译时漏了依赖。colcon build报“找不到某个头文件”十次里有八次是依赖库没装全或版本不对。排查方法是先看报错的CMakeLists.txt确认是需要什么库然后apt search找到对应系统的开发包。ROS 2里很多功能包直接要求对方包已经安装并且source过所以编译顺序和source环境特别重要。第三个是Jetson上swap分配太小。跑目标检测模型时内存不够系统卡到鼠标都动不了。后来我把系统的swap文件扩大到8GB情况缓解很多。在写服务脚本时也加了监控内存快满的时候自动清理日志缓存。很多问题都不是技术难度的问题而是提前没考虑资源边界。最后再说两句我见过太多人一上来就急着跑算法、跑仿真结果环境一塌糊涂。Module 3这门课的价值其实不是教你几个命令而是给你建立一套“遇到环境问题不慌”的排查体系。我自己的体会是环境搭建这件事越往后越像是拼图今天解决串口权限明天处理编译依赖后天搞定显卡驱动等这些碎片都拼齐了后面的开发效率才会上去。所以如果你现在正被某个环境问题卡住别烦躁那说明你正在把地基打实。后面你会发现真正消耗你的从来不是算法本身而是那些“半吊子”环境带来的不确定性。把这些基础拢好了无人机软件这条路会顺很多。