基于Dubins路径与候选集的无人机集群协同攻击仿真实现
做无人机集群协同的仿真难点从来不在单机控制而在多机之间的“协作逻辑”。目标搜索、冲突避免、联盟组建、任务执行这四个环节单拎出来任何一个写个Demo都不难但把它们串成一个闭环再加进资源分配的约束整个问题的复杂度就上来了。这篇内容要聊的就是一套基于Dubins路径模型和候选集机制、在Matlab里跑通的集群协同攻击仿真程序。这套程序解决的核心问题非常具体一群无人机进入任务区域不仅要自己找得到目标、打得着目标还得在飞行过程中互相不撞上并且当遇到高价值目标时能动态决定派谁上、用几架飞机上、每架飞机承担什么角色。换句话说它把“搜、避、联、打”四个动作整合进了同一个仿真框架里。对正在做毕业设计、竞赛项目或者刚接触多智能体协同控制的人来说这套程序的思路和代码结构可以作为一套很顺手的起步模板。1. 这个仿真的核心思路拆解1.1 为什么是Dubins路径模型先聊Dubins。标题里写的是Dubin其实完整叫法是Dubins路径这是上世纪50年代提出的一套几何方法专门解决“有最小转弯半径约束的飞行器从当前点到目标点最短路径长什么样”的问题。无人机不是质点它有个物理限制——转弯半径不能无限小。Dubins路径把这个问题变成了一个几何构造问题在固定转弯半径下从起点状态到终点状态最优路径就是“圆弧直线圆弧”的组合。这个模型在真实无人机航迹规划里用得相当多因为它算得快、轨迹可飞不是那种“纸上能飞实际做不到”的理想曲线。在这套仿真里选Dubins路径本质是给无人机的运动加了个真实的物理约束。集群协同的核心矛盾在于你不能为了让飞机按理想路线走就忽略它飞不飞得出来。很多第一次接触集群仿真的同学会把每架飞机当成全向移动的质点编队和协同倒是好写了但做出来的轨迹全是硬折线实际应用价值不大。换上Dubins模型之后每段机动都会自然带出转弯半径的影响你才会真正感受到“飞行器”和“粒子”的区别。实测下来的体会是Dubins路径的引入会让仿真结果看起来舒服很多尤其是多机同时到达目标位置时那些平滑的弧线轨迹比生硬的折线接折线要真实得多。1.2 候选集机制解决“动态环境下到底该听谁的”候选集机制是这个仿真的另一个核心概念。通俗点说每架无人机在飞行过程中不是脑子里装着全图所有目标而是只维护一个“我有机会对付的目标名单”这个名单就是候选集。为什么需要这个机制因为集群协同最怕的一件事就是全局信息过重。想象一下20架无人机如果每时每刻都要知道另外19架在哪、所有目标的实时位置、每一秒的最优分配方案通信负载和计算负载都会被拉满而且任何一条链路断了整个系统就崩了。候选集机制把这个全局问题切成了局部决策问题每架无人机根据自己的探测范围、位置关系、任务价值实时筛选出一个适合自己处理的目标子集再在子集里做决策。这个思路说穿了就是“大事化小”。全局规划只在联盟组建的一瞬间发生其余时间都是局部博弈。这种设计非常贴合真实的分布式系统架构也更容易在Matlab里做模块化实现。1.3 从搜索到执行四个环节的闭环逻辑这套程序的完整链路是这样的无人机编队起飞后先按规划路径执行目标搜索一旦某架无人机在自己的探测范围内发现目标就把它加入候选集接着需要判断当前空域有没有碰撞风险如果有先执行冲突避免机动然后根据目标的价值、自身携带的武器资源、其他无人机的相对位置决定是单机攻击还是组建联盟协同攻击最后进入任务执行阶段完成攻击后重新评估战场态势转入下一轮循环。这四步串联起来就形成了一个“搜-避-联-打”的闭环。每一轮循环都会更新候选集而候选集的变化又会反过来影响后续的搜索路径和联盟决策。资源分配这件事就是在联盟组建这个环节里被真正落地处理的。2. 四个核心模块逐个拆解2.1 目标搜索模块覆盖优先还是价值优先目标搜索模块的设计决策直接影响整个仿真后面的走向。在这套程序里搜索路径采用的是覆盖优先的策略也就是先保证探测范围尽可能覆盖整个任务区域。当然实际运行中也可以切换成价值优先模式比如已知某些区域存在高价值目标就引导无人机优先飞向那片空域。搜索模块的核心参数有三个探测半径、扫描扇区角度和无人机巡航速度。探测半径决定了候选集的天花板无人机只能发现自己探测范围内的目标扫描扇区角度决定了搜索的精细程度扇区越小单次搜索的精度越高但覆盖效率会下降巡航速度影响整体搜索节奏速度越快单位时间覆盖区域越大但留给冲突避免的响应时间就越短。2.2 冲突避免模块速度障碍法冲突避免这个环节我强烈建议使用速度障碍法。原理不复杂把每架无人机看成一个圆预测未来一段时间内两个圆的运动轨迹是否有交集如果有就计算一个速度修正量让双方错开。这套程序里的冲突避免逻辑是成对检测再统一解算的。先两两检查所有无人机之间的相对距离和相对速度筛选出有潜在碰撞风险的飞机对再对每一对进行速度解算。这里有个实操细节修正后的速度向量不能超出无人机的机动能力范围否则你算出来的避碰策略在实际飞行中是执行不了的。我踩过的坑是避碰算法的避碰优先级如果设置得太高无人机在面临“前方有敌机侧方有友机”的情况时会因为反复躲避而陷入路径震荡。后来处理方式是加了一个动态优先级任务执行阶段的无人机拥有最高通行权处于搜索阶段的无人机会主动避让。这个优先级规则简单但在仿真里极大减少了路径震荡的频次。2.3 联盟组建模块什么时候单打独斗什么时候组队联盟组建是这套程序里最精彩的部分。它的核心决策问题很直接一架无人机发现了一个目标到底该自己打还是呼叫队友一起来决策依据是目标价值和自身资源匹配度。目标价值包括目标类型、威胁等级、击毁收益等综合评分自身资源匹配度则看当前的武器类型、剩余弹药量和引信状态。如果自身资源足以完成任务就独自执行攻击如果能力不足就发起联盟请求在候选集内寻找合适的队友。联盟组建的候选集筛选逻辑是优先选择距离目标近、弹药充足、当前无任务负担的无人机。组建成功后程序会为联盟内的每架无人机分配具体的攻击角色和进入方向。这里有一个值得注意的设计细节联盟不是越大越好因为联盟越大编队内部的协调成本越高被敌方探测到的概率也越大。所以这套程序里设置了最大联盟规模限制比如单目标最多由3架无人机组成攻击编队。2.4 任务执行模块从联盟决议到末端攻击任务执行模块的核心是末端攻击阶段。在这一阶段联盟内的每架无人机需要按预设的进入航向飞向目标并在指定距离释放武器。由于采用了Dubins路径模型每架无人机的进入方向需要单独解算确保它们从不同的攻击扇区进入提高攻击成功率。在这个模块里程序和纯数学仿真有一个明显区别——它引入了一定的随机性。比如武器命中概率函数里加入了正态分布的随机扰动因子这样即使两次仿真的初始条件完全相同结果也会有细小的波动更接近真实战场的不确定性。3. 资源分配机制从“谁发现归谁”到“按能力匹配”3.1 为什么必须做资源分配很多初版集群仿真程序走的都是“谁发现目标谁就负责攻击”的简单逻辑。这个逻辑在目标数量和无人机数量都比较少的场景下出不了大问题但一旦规模上去就会出现明显的失衡离目标近的无人机弹药打光了远处的无人机却满载弹药在空域里闲逛或者多架无人机同时涌向同一个低价值目标造成了火力浪费。资源分配的意义就是打破这种天然的不均衡。每一架无人机在联盟组建时不仅要上报自己的位置和任务状态还要上报自己的资源状态——包括剩余弹药量、武器类型、燃料余量。这些信息会汇总到一个分配器里由分配器根据目标价值、攻击需求和各机资源状态给出一个“谁该去”的建议。3.2 能力-任务匹配模型在这套程序里资源分配采用的是一种简化的能力-任务匹配模型。每个目标都会被打上资源需求标签比如重甲目标需要至少2枚穿甲型弹头或者需要1枚高爆型弹头加1枚穿甲型弹头的组合。每架无人机则带有资源供给标签描述它能提供的武器数量和类型。分配器的工作就是在候选集构建的攻击联盟范围内搜索一种资源供给与资源需求匹配的组合方案。搜索不到就扩大候选范围搜索到了就把联盟确定下来。这个模型看起来简单但胜在落地性强在Matlab里用几行矩阵运算就能实现不需要复杂的整数规划求解器。3.3 候选集上的动态重分配还有一个很关键的细节资源分配不是只做一次。当某架无人机被击毁、弹药耗尽或者某个目标的实时价值发生重大变化时程序会触发重分配流程。重分配不是推翻重来而是在现有候选集基础上做局部调整。这个设计非常贴近实际战场计划赶不上变化但变化不应该导致全盘重来而是微调局部方案。在仿真中每轮主循环都会检查一次是否需要触发重分配触发条件有三个有联盟成员失去作战能力、有新目标被探测到且价值排名进入前三、有联盟完成任务进入回收阶段。多轮仿真跑下来这个机制的稳定性和计算效率都比每次全量重规划要优秀得多。4. 实操过程从搭建场景到调通主循环4.1 场景初始化我开始写这套程序时第一步是把仿真场景定义清楚。任务区域范围设定为10km×10km的方形空域无人机编队由5架组成初始位置分布在左下角形成编队队列。目标区里预设了3个静态目标分布在右半区域的三个不同位置每个目标附带价值评分。初始化代码包含几个关键的结构体无人机参数结构体位置、速度、航向角、最小转弯半径、探测半径、弹药清单、目标参数结构体位置、价值、弹药需求、仿真环境结构体区域边界、仿真步长、最大仿真时长。这一步看起来繁琐但做得越完整后面模块之间的数据传递就越顺畅。初始化阶段有一个很容易被忽略的坑无人机的最小转弯半径和仿真步长不匹配。如果转弯半径设得很大而仿真步长设得很短你会发现每步的航向变化量极小整架飞机看起来就像在画一个半径远大于设定值的圆弧路径规划的结果会和理论值有偏差。经验值是让单步航向变化不超过10度否则Dubins路径解算会产生明显的数值误差。4.2 Dubins路径生成的代码实现Dubins路径生成函数是这套程序里最需要打通的底层模块。这里给出我实现路径生成的大致逻辑和一个可以直接运行的Matlab函数框架。function [path_points, path_len] dubins_path(q0, qf, R) % q0, qf: [x, y, heading] 起点和终点状态heading用弧度表示 % R: 最小转弯半径 % 返回值: 路径点序列和路径总长度 % 1. 计算黎曼映射后的端点状态LSL, RSR, RSL, LSR等六种模式 % 2. 对每种模式计算圆-直线-圆的连接点 % 3. 选择总路径最短的模式作为最优Dubins路径 % 4. 按仿真步长对路径采样生成离散点序列 % 5. 计算路径总长度 % 这里省略具体几何推导核心代码大约80行 end核心思路就是分别计算LSL、RSR、RSL、LSR、LRL、RLR这六种机动组合的路径长度选最短的那个。实测下来无人机速度和位置更新用这种方式做整体计算开销很小一次路径重规划大概只需要几毫秒。4.3 主循环结构主循环是整个仿真的大脑采用时间步推进的方式每个仿真步长内依次执行以下更新逻辑第一步更新每架无人机的感知信息。根据当前位置和探测半径检查目标列表把落入探测范围的目标加入候选集并更新目标状态。第二步调用冲突避免模块对存在碰撞风险的所有无人机对进行速度修正。第三步检查联盟状态如果有无人机准备组建联盟或需要资源分配则触发联盟模块。第四步根据各无人机的状态搜索、集合、攻击、返航执行对应的运动控制指令位置和航向沿当前Dubins路径前进一个仿真步长。这个主循环的逻辑顺序一定要固定不能乱。我曾经把冲突避免放到感知更新之前结果一上来就用旧位置判断碰撞风险导致两架无人机在编队出航阶段就发生了逻辑上的位置重叠。4.4 候选集筛选的细节与边界条件候选集筛选是每轮感知更新后都执行的核心逻辑。在代码实现上有两个边界条件需要特别注意。一个是探测半径的边界——目标刚好在探测边界上这时目标会频繁地“进入-离开-再进入”候选集引发联盟组建的震荡。解决办法是给候选集加一个迟滞机制目标一旦进入候选集就算短暂脱离探测范围也会保留一段时间不会立刻被移除。另一个是联盟形成过程中的成员状态判断——候选集里的无人机可能正处于避让机动中如果强行让它立刻加入联盟会导致避碰算法和联盟路径规划互相打架。我最终采用的是添加一个“可调用状态”标志位无人机只有处于非避让、非攻击状态时才能响应联盟请求。5. 常见问题与排查实录5.1 路径规划震荡仿真中战斗机经常会遇到路径规划震荡问题。表现是无人机在目标周围来回绕圈始终无法进入预期的攻击位。排查方向是检查Dubins路径的终点状态是否设置正确——如果终点状态的航向角指向了目标的反方向无人机会一直在目标附近画弧线试图找一个能转回来的角度。最终定位到问题出在攻击位计算上每次迭代都让目标状态跟着新的位置变化形成了一个正反馈的死循环。解决方案是固定目标攻击位为首次识别时的位置后续所有路径规划都以这个固定点位为锚点。5.2 联盟组建死循环有一轮修改后两架无人机反复地你发请求、我发响应建完又散散了又建整个仿真陷入了联盟组建的死循环。排查后发现问题出在调用顺序上我先调用了联盟组建再调用资源分配导致成员刚确定资源分配就发现方案不合理回退到了候选集然后又触发了新一轮的联盟组建。改成先做资源分配预筛选再进入正式联盟组建流程这类死循环就消失了。这个坑值得单独记一笔联盟组建和资源分配这两件事看起来是先后关系其实是耦合的必须把资源预筛作为组建的前置条件而不是组建完成后的检验条件。5.3 路径避让失效有一次出现的问题是避让机动计算出错了但无人机还是和新相撞的友机仍然重叠了。原因是避让模块给出的躲避向量虽然正确但执行该向量之后无人机沿Dubins路径飞行时存在最小转弯半径没法按理想的躲避向量走。后来在速度障碍法解算输出后增加了一步检查对输出的躲避航向做一次可行性过滤如果躲避航向转不过去就自动退化成“减速等待”策略宁可慢一点也要保证安全距离。5.4 仿真效率骤降仿真跑到第2000步之后明显变得卡顿。分析发现是候选集矩阵每次都重新分配内存反复地扩展和释放导致Matlab的内存开销越来越大。解决方案是预分配候选集的最大尺寸矩阵用零填充占位运行时只更新非零部分。这个改动让整个仿真的运行效率提升了将近一倍。6. 一些值得一试的扩展方向这套程序跑通之后我个人建议可以往两个方向做扩展。第一个方向是引入动态目标让目标具备移动能力。整个搜索和联盟策略都会发生变化因为目标的实时位置不断变化Dubins路径的终点条件必须在线更新资源分配也要考虑到达目标的时间窗口限制难度上了一个台阶但通用性大大提升。第二个方向是给无人机加入异构特性比如用不同类型的无人机组合编队——侦察型飞得快、探测范围大攻击型载荷重、机动性差。异构编队的联盟组建策略和同构编队差异很大会涉及不同无人机的角色划分可玩性和研究价值都很高。最后再分享一个小技巧仿真里所有随机因素的种子值建议在初始化时固定下来否则每次跑出来的结果都不一样调试的时候很难定位到底是你改的代码出了问题还是随机波动导致的差异。固定随机种子让每次仿真的随机序列可复现这样改代码后的对比才有意义。这套程序我调了一个多月从最初的随机满天飞到最后能稳定复现预定作战流程关键就在于把随机种子和初始条件全部固化后续所有的优化工作才有了一个稳定可靠的参照基准。

相关新闻

AI漫剧全流程制作:从剧本到成片的零基础技术路径

AI漫剧全流程制作:从剧本到成片的零基础技术路径

B站有一套 AI 漫剧教程,标题很夸张:全 666 集,198 小时,零基础入门,还允许白嫖。很多人第一反应是标题党,但仔细看它列出的内容板块——剧本、分镜、静帧、视频、配音、剪辑、保持人物一致——这正是目前 A…

2026/10/19 2:22:37 阅读更多 →
小鹏MONA零接管跑山背后:智驾感知、规划与控制全链路解析

小鹏MONA零接管跑山背后:智驾感知、规划与控制全链路解析

零接管跑山登顶背后:小鹏MONA智驾的技术看点、验证方法与安全边界“完全是老司机水平”“零接管登顶”……最近小鹏 MONA 辅助驾驶跑山的讨论,标题一个比一个猛。作为长期关注智驾技术栈的程序员,我第一反应不是情绪,而是三个问题…

2026/10/19 2:22:37 阅读更多 →
豆包+即梦5.0+LibTV:AI短剧多主体一致性的全流程生产链路

豆包+即梦5.0+LibTV:AI短剧多主体一致性的全流程生产链路

做 AI 短剧,最让人头疼的不是画面不够精致,而是角色前后不一致。第一镜里还是长发白衣的女主,第三镜就变成了短发黑裙,观众一眼就能看出是“拼接货”。这次分享的“豆包 即梦5.0 LibTV”组合,核心就是解决多主体一致…

2026/10/19 2:22:37 阅读更多 →

最新新闻

Flink有界流与无界流:核心区别、运行时行为差异与选型避坑指南

Flink有界流与无界流:核心区别、运行时行为差异与选型避坑指南

1. 从一个反直觉的现象说起:为什么批处理跑得好好的,换成流处理就出问题刚接触 Flink 的人,十有八九会在某个时刻被一个看似简单的问题绊住:我明明写的是同一套算子逻辑,为什么换成流模式跑,结果要么迟迟不…

2026/10/19 3:14:03 阅读更多 →
Hadoop期末复习全攻略:HDFS、MapReduce与YARN核心考点精讲

Hadoop期末复习全攻略:HDFS、MapReduce与YARN核心考点精讲

1. 这门课到底在考什么:从一张复习卷看Hadoop知识体系的全貌每年到了期末季,总有一批同学在群里哀嚎:“Hadoop这东西,课上听懂了,一到做题就懵。”我当年带过几届大数据方向的课程助教,也帮不少朋友梳理过复…

2026/10/19 3:14:03 阅读更多 →
Halcon基于形状的模板匹配:原理、参数调优与实战经验

Halcon基于形状的模板匹配:原理、参数调优与实战经验

做视觉项目这些年,经常碰到有人问我:Halcon 里做定位用哪个方法最稳?我的回答往往不是特征点,也不是深度学习,而是那个看起来有点“老派”的——基于形状的模板识别。尤其当你面对的是低纹理的金属件、注塑件&#xff…

2026/10/19 3:14:03 阅读更多 →
基于PSO的LLC变换器PI参数自动寻优MATLAB仿真项目解析

基于PSO的LLC变换器PI参数自动寻优MATLAB仿真项目解析

简介:本资源为基于MATLAB的PSO-PID控制器参数优化实现工程,面向控制工程初学者、自动化专业学生及需要摆脱人工试凑整定PID参数的开发人员。压缩包内共3个文件,其中2个m脚本分别实现粒子群优化主程序与PID参数求解逻辑,1个mdl模型…

2026/10/19 3:14:03 阅读更多 →
SenseNova-U1.5-8B-MoT-pose-bf16完全介绍:跑在Apple Silicon上的开源AI姿态迁移模型是什么

SenseNova-U1.5-8B-MoT-pose-bf16完全介绍:跑在Apple Silicon上的开源AI姿态迁移模型是什么

【免费下载链接】SenseNova-U1.5-8B-MoT-pose-bf16 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/SenseNova-U1.5-8B-MoT-pose-bf16 点击查看 免费下载 SenseNova-U1.5-8B-MoT-pose-bf16 是一款跑在 Apple Silicon(M 系列芯片&#xff0…

2026/10/19 3:14:03 阅读更多 →
AI可复现性挑战:固定随机种子、锁定环境,让训练结果稳定复现

AI可复现性挑战:固定随机种子、锁定环境,让训练结果稳定复现

1. 从一次“幽灵复现失败”说起:到底什么是AI的可复现性挑战前阵子我把一台GPU服务器上的旧训练任务重新跑了一遍,用的确实是当时的代码、当时的数据文件、当时的依赖环境,结果AUC从0.713变成了0.704。当时我的第一反应不是“代码写错了”&am…

2026/10/19 3:13:03 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →