ArduPilot仿真环境搭建全攻略:从Ubuntu配置到SITL调试
1. 项目概述为什么ArduPilot仿真环境搭建是个“技术活”如果你正在看这篇文章大概率是刚接触ArduPilot或者被PX4、XTDrone等仿真方案搞得眼花缭乱最终决定从ArduPilot这个“老牌劲旅”入手。我得说你选了一条既经典又充满挑战的路。ArduPilot的仿真环境搭建远不是运行一个安装脚本那么简单它更像是一个系统工程涉及操作系统、编译工具链、仿真器、地面站软件以及它们之间错综复杂的依赖关系。我见过太多新手包括几年前的我自己在“sudo apt-get install”和一堆编译错误中耗尽热情最终卡在某个诡异的链接错误或权限问题上。这个过程之所以“艰辛”核心在于它要求开发者同时具备系统管理、软件编译和无人机领域知识的复合能力。这不是一个简单的“下一步”安装向导而是一个需要你理解背后原理并亲手搭建整个工具链的实践。本文将带你完整走一遍这个流程不仅告诉你每一步怎么做更重要的是解释“为什么这么做”以及分享那些官方文档里不会写的“坑”和技巧目标是让你从“搭建环境”的泥潭里爬出来真正开始享受飞控算法开发和测试的乐趣。2. 核心思路与工具链选型理解仿真生态的“四梁八柱”在动手敲命令之前我们必须先理清ArduPilot仿真环境的整体架构。盲目安装只会导致依赖地狱。整个仿真体系可以看作由四个核心支柱构成飞控固件Firmware、仿真器Simulator、地面站Ground Control Station, GCS以及硬件在环HITL/SITL接口。2.1 飞控固件代码的归宿ArduPilot固件本身是一套庞大的C/C代码库运行在飞控板如Pixhawk系列的微控制器上。仿真的第一步就是把这套代码编译成能在你电脑通常是x86_64架构上运行的程序而不是ARM架构的二进制文件。这就是SITLSoftware In The Loop的核心概念。2.2 仿真器虚拟的天空光有飞控代码还不够它需要感知环境并做出反应。仿真器就是提供这个虚拟物理环境的软件。ArduPilot主要支持以下几种jMAVSim: 轻量级、基于Java的仿真器启动快资源占用小非常适合算法快速迭代和CI/CD测试。缺点是图形界面简单物理模型相对基础。Gazebo: 功能强大的机器人仿真平台物理引擎逼真传感器模型丰富支持复杂的多旋翼、固定翼、船、潜水器模型并能模拟风、光照等环境因素。它是进行高保真仿真的首选但资源消耗大安装配置复杂。AirSim: 基于Unreal Engine/Unity的仿真器以极其逼真的视觉环境和基于物理的渲染见长特别适合计算机视觉、感知相关的算法开发。它对系统性能要求最高。对于初学者和大多数开发场景我强烈建议从jMAVSim开始。它能让你在几分钟内看到飞机“飞起来”快速建立信心和验证流程。等到需要测试更复杂的动力学或传感器模型时再挑战Gazebo。2.3 地面站软件指挥中心你需要一个界面来监控飞行状态、发送指令、调整参数。这就是地面站软件。Mission Planner (Windows): 功能全面生态成熟是Windows用户的不二之选。QGroundControl (跨平台): 界面现代跨平台支持好Windows, macOS, Linux是官方推荐且活跃开发的地面站。 在我们的仿真环境中地面站通过UDP网络协议与SITL飞控程序通信。2.4 工具链构建一切的基石这是搭建过程中最容易出问题的地方。你需要编译工具链: 将ArduPilot C代码编译为本地可执行文件。在Ubuntu上主要是gcc,g,make以及处理ArduPilot特定模块所需的python3和pip。仿真器依赖: 例如编译jMAVSim需要Java运行时而Gazebo需要一整套餐的3D渲染和物理引擎库。系统配置: 包括正确的用户组权限确保你能访问串口对于后续真机调试至关重要、环境变量设置等。注意很多教程直接给出apt命令列表却不解释每个包的作用。这导致一旦出现缺失依赖你完全无从下手。接下来的章节我会把关键依赖包的作用一并说明。3. 实操环境搭建从零开始的Ubuntu系统配置我假设你使用一台干净的Ubuntu 20.04或22.04 LTS系统这是兼容性最好的选择。Windows下的WSL2虽然可行但在网络配置和硬件访问上会有额外麻烦对于纯仿真学习尚可若涉及后续真机连接则推荐原生Linux或双系统。3.1 系统基础准备与依赖安装首先更新系统并安装最核心的编译工具和版本管理工具。sudo apt update sudo apt upgrade -y sudo apt install git zip qtcreator cmake build-essential -ybuild-essential: 包含了gcc,g,make等核心编译工具。git: 用于克隆ArduPilot源码。cmake: ArduPilot的构建系统之一它同时支持waf和cmake我们主要用waf但某些依赖需要cmake。qtcreator: 可选但作为强大的C IDE对于后续阅读和调试代码非常有帮助。接下来安装ArduPilot SITL和工具链所需的特定依赖。这是一条较长的命令但请务必一次性安装避免后续缺库。sudo apt install python3-dev python3-pip python3-matplotlib python3-lxml python3-yaml python3-serial python3-numpy python3-scipy python3-pexpect python3-opencv python3-wxgtk4.0 python3-tk python3-psutil python3-packaging python3-future python3-jinja2 python3-empy python3-argcomplete python3-argparse python3-setuptools python3-wheel python3-venv python3-dev -y这里的关键包解释python3-dev: 包含Python头文件用于编译需要链接Python的C扩展。python3-empy: 一个模板工具ArduPilot大量使用.em模板文件来生成代码。python3-argcomplete: 为命令行工具提供自动补全功能。python3-jinja2: 另一个模板引擎用于某些配置生成。3.2 配置Python环境与安装MAVProxyArduPilot的构建系统waf是基于Python的。为了避免系统Python包冲突最佳实践是使用Python虚拟环境。但经过多次实践对于ArduPilot这种深度集成系统工具链的项目直接使用pip3安装到用户目录--user更稳定。 安装关键的Python包和地面站代理工具MAVProxypip3 install --user pyserial empy catkin_pkg dronecan pymavlink mavproxypymavlink: MAVLink通信协议的Python实现是飞控与地面站通信的基石。mavproxy: 一个功能极其强大的MAVLink地面站代理和命令行工具。它不仅可以转发数据还能运行脚本、显示数据流是高级用户和调试的利器。安装后需要将用户bin目录加入PATH。echo export PATH$HOME/.local/bin:$PATH ~/.bashrc source ~/.bashrc验证MAVProxy安装mavproxy.py --version。3.3 获取ArduPilot源代码不建议直接下载zip包因为后续更新和子模块管理会很麻烦。使用git克隆并初始化子模块cd ~ git clone https://github.com/ArduPilot/ardupilot.git cd ardupilot git submodule update --init --recursive这个过程会下载数GB的数据时间较长请保持网络通畅。--recursive参数至关重要它会拉取所有必要的子模块库如传感器驱动库。3.4 安装仿真器依赖以jMAVSim和Gazebo为例jMAVSim: 它需要Java。安装OpenJDK即可。sudo apt install openjdk-11-jre openjdk-11-jdk -yGazebo: 安装过程较为复杂。推荐使用官方的一键安装脚本它会配置正确的软件源和依赖。sudo apt install wget wget https://raw.githubusercontent.com/ArduPilot/ardupilot/master/Tools/environment_install/install-prereqs-ubuntu.sh -O /tmp/install-prereqs.sh bash /tmp/install-prereqs.sh -y这个脚本运行时间较长它会安装Gazebo、ROS可选、以及一大堆图形和开发库。完成后务必按照脚本最后的提示执行source ~/.profile以更新环境变量这是很多同学忽略导致Gazebo找不到模型的关键一步。4. 编译与运行你的第一次仿真环境就绪现在进入激动人心的环节让代码跑起来。4.1 编译SITL固件在ardupilot目录下使用waf构建系统进行编译。我们以编译四旋翼Quadcopter的SITL版本为例cd ~/ardupilot ./waf configure --board sitl ./waf copter./waf configure --board sitl: 配置构建环境目标板为sitl软件在环。./waf copter: 编译多旋翼飞行器Copter固件。如果你想编译固定翼plane或小车rover则将copter替换为plane或rover。编译过程可能需要10-30分钟取决于你的CPU性能。首次编译会构建所有依赖库。如果遇到编译错误请仔细阅读错误信息。最常见的问题是依赖缺失或子模块未正确初始化。确保你完成了git submodule update --init --recursive。4.2 使用jMAVSim运行仿真编译成功后在~/ardupilot目录下运行以下命令启动一个最简单的四旋翼仿真sim_vehicle.py -v ArduCopter -f quad --console --map让我拆解这个命令sim_vehicle.py: 这是ArduPilot提供的超级方便的仿真启动脚本它帮你处理了启动SITL实例、启动仿真器、连接MAVProxy等一系列繁琐步骤。-v ArduCopter: 指定车辆类型为ArduCopter。-f quad: 指定帧类型为quad四旋翼。其他如hexa六旋翼、y6Y6布局等。--console: 打开MAVProxy控制台。--map: 打开内置的简易地图窗口。如果一切顺利你将看到终端开始滚动日志一个jMAVSim的3D窗口会弹出显示一个四旋翼模型同时一个地图窗口也会打开。在MAVProxy控制台终端窗口中你可以输入命令例如arm throttle解锁电机mode guided切换到引导模式然后takeoff 10命令飞机起飞到10米高度。4.3 连接地面站QGroundControl仿真运行后SITL默认会在本地UDP端口14550上监听。你只需要打开QGroundControl它通常会自动连接上这个端口的飞行器。如果没有可以在QGroundControl的“设置”-“Comm Links”中添加一个UDP连接地址为127.0.0.1端口14550。连接成功后你就能在地面站上看到所有飞行数据、仪表和地图并能通过地面站进行任务规划和控制。5. 进阶配置与深度避坑指南如果你成功完成了第4步恭喜你你已经完成了最基础的搭建。但真实的开发环境总会遇到更多问题。5.1 Gazebo仿真配置与常见问题使用Gazebo启动仿真只需在sim_vehicle.py命令中通过-I参数指定实例号因为默认的0被jMAVSim占用并用-m指定MAVLink端口。sim_vehicle.py -v ArduCopter -f gazebo-iris -I1 --console --map -m mavlink.py --udp-client 127.0.0.1:14551-f gazebo-iris: 使用Gazebo的Iris模型。-I1: 设置实例号为1。-m ...: 手动指定MAVLink通信参数连接到14551端口避免与jMAVSim默认的14550冲突。Gazebo启动失败常见原因模型下载失败: Gazebo首次启动会从网络下载机器人模型国内网络可能很慢或失败。解决方案使用离线模型包。可以手动下载https://github.com/osrf/gazebo_models仓库将其内容解压到~/.gazebo/models/目录下。通过环境变量设置更快的镜像源如中科大源但Gazebo模型下载的优化比较复杂。权限问题: 确保你的用户有权限访问/dev下的设备如用于Joystick。将用户加入dialout和plugdev组通常有帮助sudo usermod -a -G dialout,plugdev $USER然后注销并重新登录生效。环境变量未生效: 运行完install-prereqs.sh后没有source ~/.profile导致Gazebo找不到关键的库路径。请务必执行。5.2 多飞行器仿真与网络配置有时你需要测试多机协同。这需要启动多个SITL实例并确保它们的MAVLink端口不冲突。# 终端1启动第一个实例使用UDP端口14550 sim_vehicle.py -v ArduCopter -f quad -I0 --console --map --out127.0.0.1:14550 # 终端2启动第二个实例使用UDP端口14551并连接到第一个实例的14560端口用于机间通信 sim_vehicle.py -v ArduCopter -f quad -I1 --console --map --out127.0.0.1:14551 --out127.0.0.1:14561在第二个命令中--out127.0.0.1:14561使得实例2的数据也会发送到14561端口。你可以在第一个实例的MAVProxy中通过output add 127.0.0.1:14561命令来接收第二个实例的数据从而实现相互可见。5.3 代码调试与开发工作流搭建环境不只是为了运行更是为了开发。你需要一个高效的调试流程。编译加速: 后续修改代码后无需完全清理编译。使用./waf --targets bin/arducopter可以只编译特定目标或者直接./waf copterwaf的增量编译通常很快。使用IDE: 强烈推荐使用VSCode或QtCreator。在VSCode中打开~/ardupilot目录安装C/C插件。然后你可以使用CMake Tools插件通过ardupilot/CMakeLists.txt来配置项目它能提供代码跳转、智能提示和断点调试功能结合GDB。对于SITL调试你需要先启动仿真然后在VSCode中附加到arducopter进程。参数调试: 仿真时调整参数非常安全。在MAVProxy控制台中使用param set PARAM_NAME VALUE来修改参数例如param set PILOT_SPEED_UP 200。修改后参数只存在于内存中输入param save可将其保存到虚拟的“EEPROM”中下次启动仿真时会自动加载。6. 疑难杂症排查实录这里记录了我踩过的一些典型坑和解决方案希望能帮你节省数小时的搜索时间。6.1 编译错误“fatal error: xxx.h: No such file or directory”这几乎是必遇问题。原因和解决步骤子模块未更新: 这是最常见原因。确保在ardupilot根目录执行了git submodule update --init --recursive。有时网络问题会导致子模块拉取不全可以尝试删除modules目录重新执行。依赖库未安装: 错误信息中会提示缺失的头文件属于哪个库。例如缺少SDL.h你需要安装libsdl2-dev。使用apt search来查找对应的开发包。一个万能的方法是再次运行或检查Tools/environment_install/install-prereqs-ubuntu.sh脚本的内容看是否遗漏了某个部分。Python包缺失: 如果错误与Python相关确保已安装python3-dev和python3-pip并用pip3 install --user安装了必要的包如future,empy等。6.2 仿真启动失败“Exception in thread “main” java.lang.UnsupportedClassVersionError”这是jMAVSim的Java版本不兼容问题。Ubuntu 22.04默认可能安装Java 17而jMAVSim可能兼容Java 11更好。解决方案# 确保安装了Java 11 sudo apt install openjdk-11-jre # 如果系统有多个Java版本使用update-alternatives配置默认版本 sudo update-alternatives --config java # 然后在弹出的列表中选择Java 11对应的编号。6.3 MAVProxy或地面站连接不上SITL症状仿真启动了但MAVProxy控制台不断重连或者QGroundControl找不到飞行器。检查端口占用: 使用netstat -anp | grep 1455查看14550、14551等端口是否被其他程序占用。检查启动参数: 确保sim_vehicle.py命令中没有错误的--out参数。一个干净的启动命令应该是sim_vehicle.py -v ArduCopter -f quad --console --map。如果手动指定了-m或--out要确保端口号一致。防火墙问题: 在Linux上本地回环地址的UDP通信通常不受防火墙影响但如果你配置了复杂的防火墙规则可能需要放行。对于初学者可以暂时用sudo ufw disable关闭防火墙测试测试后记得重新开启。查看SITL输出: 在启动sim_vehicle.py的终端里观察最初的输出信息看是否有“Waiting for connection on 0.0.0.0:14550”这样的字样这表示SITL正在正确监听。6.4 Gazebo黑屏或模型悬空Gazebo窗口打开但只有网格地面没有飞机模型或者模型悬在半空不动。等待模型加载: 首次启动Gazebo加载世界和模型可能需要几分钟请耐心等待终端输出稳定。检查环境变量: 这是最可能的原因。确保已执行source ~/.profile。可以输入echo $GAZEBO_MODEL_PATH和echo $GAZEBO_RESOURCE_PATH查看路径是否包含ArduPilot的模型目录如~/ardupilot/Tools/simulation/gazebo/models。手动指定世界文件: 在sim_vehicle.py命令后添加-w参数指定一个简单的世界例如-w empty。sim_vehicle.py -v ArduCopter -f gazebo-iris -I1 --console --map -w empty搭建ArduPilot仿真环境的过程本质上是对一个复杂开源项目构建和运行体系的理解过程。它没有一键安装的捷径每一个错误都是学习其架构的机会。我的建议是按照本文的步骤建立一个纯净的Ubuntu环境耐心地走通整个流程。一旦你的第一个jMAVSim仿真成功起飞后续的Gazebo、多机、乃至真机调试都将是在此基础上叠加技能。这个环境将成为你探索无人机软件世界最强大的实验场。记住终端里红色的错误信息不是终点而是通往理解的路标。

相关新闻

AI驱动SketchUp建模:Codex与MCP协议环境配置实战指南

AI驱动SketchUp建模:Codex与MCP协议环境配置实战指南

如果你是一名建筑设计师、室内设计师或3D建模爱好者,是否曾有过这样的体验:面对一个复杂的建筑模型,你需要在SketchUp里反复推敲、手动调整每一个构件,耗费数小时甚至数天时间。或者,当你有一个初步的创意草图时&#…

2026/10/20 3:46:51 阅读更多 →
AiZynthFinder:为什么这个开源逆合成工具是化学研究的终极选择

AiZynthFinder:为什么这个开源逆合成工具是化学研究的终极选择

AiZynthFinder:为什么这个开源逆合成工具是化学研究的终极选择 【免费下载链接】aizynthfinder A tool for retrosynthetic planning 项目地址: https://gitcode.com/gh_mirrors/ai/aizynthfinder 在化学合成研究中,你是否曾为寻找最优合成路径而…

2026/10/17 12:31:08 阅读更多 →
Ubuntu 22.04 NFS部署实战:从原理到生产环境配置

Ubuntu 22.04 NFS部署实战:从原理到生产环境配置

1. 项目概述:为什么在Ubuntu 22.04上部署NFS是刚需? 如果你在管理一个开发团队,或者手头有几台服务器需要共享数据,那么“网络文件系统”这个概念你一定不陌生。NFS,这个诞生于上世纪80年代的协议,至今依然…

2026/10/18 16:47:00 阅读更多 →

最新新闻

数据链路层核心原理:MAC地址、以太网帧与交换机转发机制解析

数据链路层核心原理:MAC地址、以太网帧与交换机转发机制解析

十年前我第一次在模拟器里敲下 show mac address-table,看着那几行 MAC 和端口映射,并不觉得数据链路层有什么特别。直到后来排障时发现,很多网络“通了却不对”的问题,根源都藏在这一层。数据链路层是连接物理传输与网络逻辑之间…

2026/10/20 5:22:05 阅读更多 →
信呼OA v1.9.1部署与流程实战:中小团队生产级协同底座

信呼OA v1.9.1部署与流程实战:中小团队生产级协同底座

简介:信呼协同办公OA系统v1.9.1是一款面向中小企业及IT运维/开发人员的开源办公平台解决方案,旨在解决多终端协作、流程标准化与系统可定制化等核心管理需求。资源包共1256个文件,主体为606个PHP后端逻辑文件、231个GIF/79个PNG/3个JPG等前端…

2026/10/20 5:22:05 阅读更多 →
jstat实战:用JDK自带工具监控JVM内存与GC

jstat实战:用JDK自带工具监控JVM内存与GC

在Java服务卡顿、内存飙高、接口超时的时候,绝大多数人第一反应是抓一把jstack看线程,或者拉一份heap dump慢慢分析。但很多时候,问题的根源根本不在某个线程卡在哪行代码,而是整个堆的“新陈代谢”出了问题——对象疯狂创建、回收…

2026/10/20 5:22:05 阅读更多 →
Yume1.5交互式世界生成实战:单卡12FPS实时渲染与部署全解析

Yume1.5交互式世界生成实战:单卡12FPS实时渲染与部署全解析

第一次在某个开源项目页里看到“单卡 12 FPS 实时交互渲染”这句话,我还以为是拿预渲染视频抽帧充数。直到自己把提示词敲进去,生成出一片雨夜小巷,拖动路灯,地上的积水反光跟着偏移角度的那一刻,我才确定:…

2026/10/20 5:22:05 阅读更多 →
c++11学习

c++11学习

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

2026/10/20 5:22:05 阅读更多 →
视觉模型重塑时间序列分析:从离散Token到连续视觉的范式转换

视觉模型重塑时间序列分析:从离散Token到连续视觉的范式转换

1. 从离散Token到连续视觉:时间序列分析的新思路拆解时间序列分析这个领域,做的人多,但真正让人眼前一亮的突破少。传统方法从统计模型一路走到深度学习,Transformer架构进来之后,大家发现一个尴尬的事实:文…

2026/10/20 5:21:04 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/18 12:16:16 阅读更多 →