目录

MATLAB实现基于GA-DNN-RNN 遗传算法(GA)结合深度神经网络(DNN)与循环神经网络(RNN)进行无人机三维路径规划的详细项目实例... 2

项目背景介绍... 2

项目目标与意义... 3

提升复杂三维环境下路径规划的全局最优性... 3

提升路径规划在动态环境中的适应性与鲁棒性... 4

构建可扩展的智能路径规划算法框架... 4

推动智能优化与深度学习在航空航天领域的交叉应用... 4

项目挑战及解决方案... 5

高维连续空间路径编码与搜索复杂度挑战... 5

深度网络训练样本构建与泛化能力挑战... 5

多目标、多约束统一建模与实时计算挑战... 6

项目模型架构... 6

总体架构与数据流设计... 6

环境建模与三维代价场构造... 7

DNN模块的结构设计与功能定位... 7

RNN模块的序列建模能力与角色... 7

GA与DNN-RNN耦合的优化机制... 8

项目模型描述及代码示例... 8

三维环境构建与地形生成示例... 8

路径参数化与初始路径生成示例... 9

DNN局部代价预测网络构建与训练示例... 10

RNN时序代价预测网络构建与训练示例... 12

适应度函数与路径代价评估示例... 13

遗传算法配置与路径优化主程序示例... 15

MATLAB实现基于GA-DNN-RNN 遗传算法(GA)结合深度神经网络(DNN)与循环神经网络(RNN)进行无人机三维路径规划的详细项目实例

请注意此篇内容只是一个项目介绍 更多详细内容可直接联系博主本人 

 或者访问对应标题的完整博客或者文档下载页面(含完整的程序,GUI设计和代码详解)

面向城市低空物流、应急救援与巡检等任务,无人机三维路径规划已经从概念研究走向工程落地。在复杂的三维空间中,无人机不仅要在起点与终点之间找到一条可行路径,更要在多维约束下实现能量消耗最小、飞行时间最短、安全裕度最大等多目标综合优化。传统路径规划方法,如三维栅格搜索、改进A算法、Dijkstra算法、RRT/RRT等,在规则环境与约束相对简单的场景中表现良好,但在高动态、高不确定性的真实应用环境中,往往存在搜索空间爆炸、计算时间过长、对环境变化适应能力差等问题。尤其在城市峡谷、山地峡谷、复杂障碍群的背景下,单纯依靠几何搜索或局部优化,难以兼顾全局最优性与实时性。

随着深度学习技术以及元启发式优化算法的发展,将智能优化算法与深度神经网络结合,引入强化的学习和记忆能力,为无人机三维路径规划提供了新的解决思路。深度神经网络可以在大量历史数据与仿真数据中学习复杂环境下的隐含规律,而循环神经网络擅长处理时序信息与状态序列,能够对无人机飞行过程中的动态变化进行建模和预测。遗传算法作为一种典型的全局优化方法,在处理非线性、多峰值、多约束的复杂优化问题时具有鲁棒性强、不依赖梯度信息等优势,但单独使用时在高维空间通常面临收敛速度较慢、易陷入局部次优区域的问题。将遗传算法与DNN、RNN进行有机融合,一方面可以借助网络模型对环境特征与状态转移规律进行学习,提升搜索方向的智能性;另一方面又可以利用遗传算法对网络参数或路径编码进行全局优化,改善传统深度学习依赖梯度下降的局限,从而形成面向复杂三维环境的智能路径规划框架。

在实际应用背景中,无人机需要面对多类型约束。例如,地形高度约束要求飞行高度必须高于地形表面一定安全裕度;禁飞区和限高区要求飞行路径不能穿越特定空间区域;风场、多径干扰、通信中断等因素会影响飞行安全与航迹可控性;电池容量限制要求整体路径在能量消耗上满足可行性;而任务需求却可能要求在最短时间达成覆盖、巡查或运送。传统单一指标优化难以满足这些复杂需求,因此多目标、多约束的路径规划成为研究重点。基于GA-DNN-RNN的三维路径规划项目正是针对这一背景展开,将环境特征、无人机动力学、任务需求与安全约束统一在一个可优化的数学框架内,通过智能算法探索高维策略空间。

在数据层面,三维路径规划不仅包含空间坐标信息,还要考虑无人机姿态、速度、加速度、能量消耗率以及环境风险分布等多维特征。DNN可用于从高维状态空间中提取关键特征、构建风险评估或成本预测模型;RNN则用于建模时间维度上连续状态的演化,如预测下一时刻的安全代价、能耗变化或轨迹偏差。遗传算法可以在路径编码空间中进行演化搜索,通过选择、交叉和变异操作逐步逼近更加优越的路径方案,同时利用DNN和RNN提供的代价函数与预测信息,提高个体评价的准确性与搜索效率。

从工程实践角度,基于GA-DNN-RNN的路径规划不仅适用于单机任务,也为多机协同提供了基础。通过对路径的全局优化,能够减少无人机之间的潜在冲突,规划合理的空域分配和时间分配方案,实现安全有序的低空交通管理。在应急救援场景中,这种方法能够在灾后复杂地形和受损基础设施环境中快速生成安全路径,为物资投送、实时监测提供支撑;在电力巡检与管线巡检中,可以根据设备分布、地形障碍和作业规范生成高安全性、低重复度的巡检路径,提升作业效率和安全等级。

在技术栈方面,MATLAB结合其深度学习工具箱、优化工具箱与信号处理能力,为构建GA-DNN-RNN一体化路径规划框架提供了良好的实验平台。尤其在R2025b版本中,对深度学习和自定义训练流程的支持更加成熟,有利于在同一环境下完成数据生成、网络训练、遗传优化与三维可视化展示。通过合理的网络结构设计与编码策略,使得遗传算法可直接对DNN和RNN的超参数、网络结构或路径控制点进行优化,实现从“路径搜索”到“模型增强”的双重目标。

基于上述背景,基于GA-DNN-RNN的无人机三维路径规划项目不仅具有理论探索价值,更具有直接的工程落地潜力。通过这一项目,可以系统地研究智能优化与深度学习在路径规划问题上的协同作用,形成一套兼具全局性、灵活性与可扩展性的解决方案,为新一代智能无人机任务规划与调度提供可靠技术支撑。

项目目标与意义

提升复杂三维环境下路径规划的全局最优性

针对复杂三维环境,经常遇到障碍分布不规则、禁飞区形状复杂、风险区域呈现多峰特性等情况,传统启发式搜索往往依赖局部信息,容易在局部可行区域中形成“围栏效应”,导致路径绕行过长或陷入局部最优。本项目的目标之一是在完整三维空域中实现更加接近全局最优的路径规划。通过将遗传算法作为全局搜索核心,将路径编码为一组空间控制点或参数化轨迹,再结合DNN学习得到的三维代价场分布,可以在搜索过程中更快识别高风险区域和低成本通道,从而引导遗传算法的种群朝着真正低成本的方向演化。RNN则在时间维度对候选路径进行动态评估,预测未来时刻可能出现的风险变化和能量消耗趋势,帮助评价一个路径方案在全任务周期内的整体优劣。这样的设计使得路径规划不仅仅关注几何距离,还综合考虑能耗、安全性和时间等因素,使所得路径更符合全局最优目标,为实际任务执行提供更可靠的决策基础。

提升路径规划在动态环境中的适应性与鲁棒性

复杂空域往往处于动态变化之中,例如临时禁飞区、移动障碍物、突发风场变化等因素都会对规划结果产生影响。纯静态规划方法在这种场景下经常失效,必须频繁重新规划路径,影响任务效率。本项目的另一重要目标是提高路径规划方法对动态环境的适应能力和对不确定性的鲁棒性。通过RNN对历史飞行状态和环境变化进行建模,可以在路径规划阶段融入对未来环境变化的预测信息,使规划结果具有预见性。例如,在预期风场增强或信号衰减区域,提前规划更为保守的航迹或预留安全冗余。同时,利用遗传算法在路径空间进行多样化搜索,保持种群中一定比例的探索型个体,可以在环境突变时提供备用候选路径,降低单一路径失效带来的风险。DNN则在多源数据输入下提供复杂环境特征的表达能力,使规划系统能够在不同任务场景和传感器配置下保持稳定的性能表现。

构建可扩展的智能路径规划算法框架

无人机应用领域具有极强的多样性,从短距快递到长航时巡线,从单机作业到集群协同,对路径规划算法的需求存在较大差异。如果每种应用场景都重新设计一套完全不同的规划算法,工程成本高且维护困难。本项目的目标之一是构建一个可扩展、可迁移的智能路径规划算法框架。通过合理设计GA-DNN-RNN的模块边界,将环境建模、代价评估、时序学习和全局优化解耦,同时保留模块间的接口,可以在不同任务中重新组合或替换部分模块。例如,可以根据任务重点切换不同代价函数,实现从能耗最优到时间最优、从单机安全到多机协同等多种规划目标。DNN和RNN结构可根据数据规模和任务复杂度进行扩展,而遗传算法的编码方式和适应度函数也可灵活调整。这种框架化设计有利于在MATLAB环境中快速验证新想法和新算法,为后续产业应用奠定基础。

推动智能优化与深度学习在航空航天领域的交叉应用

智能优化算法与深度学习已经在图像识别、自然语言处理等领域取得突出成绩,而在航空航天、无人系统等高安全性领域的交叉应用仍在快速发展阶段。本项目通过将GA、DNN与RNN有机结合,构建一个实际可运行的无人机三维路径规划实例,有助于探索智能优化与深度学习在航空航天应用中的可行模式。通过对比单独使用遗传算法、单独使用深度学习模型以及二者融合的性能差异,可以深入理解各自优势和局限,为后续在航迹控制、多机协同决策、任务规划等方向推广类似的融合方法提供经验。与此同时,基于MATLAB R2025b平台构建的完整实现,方便研究人员与工程师在同一环境中进行仿真、调参与可视化展示,降低交叉应用的门槛,推动更多多学科交叉研究落地。

项目挑战及解决方案

高维连续空间路径编码与搜索复杂度挑战

三维路径规划涉及连续空间,路径本身通常是连续曲线而非有限离散节点。直接在连续空间中使用遗传算法进行搜索时,路径编码会引入大量自由度,例如几十到上百个控制点,每个控制点包含三维坐标或附加的姿态参数,导致搜索空间维度急剧上升。维度增加会显著提高遗传算法的收敛难度和计算成本,并带来早熟收敛到局部最优解的风险。为解决这一挑战,需要设计合理的路径参数化方式,将复杂的连续路径压缩到更低维的参数空间。例如使用分段Bezier曲线或三次样条曲线,仅优化有限数量的控制点。遗传算法操作在控制点空间执行,通过解码过程将参数转为高分辨率路径轨迹,再由DNN和RNN进行代价评估。为进一步降低搜索复杂度,可引入分层规划思想,在粗粒度的全局规划基础上,再进行局部精细化调整。MATLAB环境下可以用向量化运算和并行运算工具加速路径样条生成、代价计算和约束检测,通过精心设计的编码与解码策略,使遗传算法在高维环境下仍保持可接受的搜索效率与收敛性能。

深度网络训练样本构建与泛化能力挑战

DNN与RNN的性能高度依赖高质量训练数据。无人机三维路径规划中涉及的环境形式多样,包括地形起伏、建筑物分布、临时障碍以及气象因素,实际测量数据难以覆盖所有情况。仅依赖少量真实数据训练深度网络容易出现过拟合,导致在新场景中性能急剧下降。为解决这一挑战,需要建立合理的仿真数据生成流程,将物理模型与统计模型相结合,构造多样化的训练样本集。可在MATLAB中利用随机场模型生成地形和障碍分布,叠加不同的禁飞区配置和风场模式,自动生成大量三维环境样本与对应的路径代价标签。DNN负责从静态环境特征中回归局部代价或安全风险,而RNN则利用路径序列和历史状态构建时序代价预测模型。为了增强泛化能力,可以使用噪声注入、多场景混合训练和正则化技术,并通过遗传算法优化网络的部分结构超参数,在有限的训练样本条件下获得更高的预测准确度。通过交叉验证与场景分组测试,可以识别网络结构中的薄弱环节,逐步提高模型的鲁棒性和迁移能力。

多目标、多约束统一建模与实时计算挑战

无人机三维路径规划往往不止一个目标,需要同时考虑能耗、飞行时间、航迹平滑度、安全距离以及对禁飞区的严格约束。在数学建模时,多目标可能存在冲突,例如缩短时间往往会增加能耗和风险,增加安全裕度又可能延长航程。如何将多目标、多约束统一到一个可被遗传算法优化的适应度函数中,同时又不损失对不同目标的灵活控制,是一个关键挑战。同时,规划结果需要在接近实时的时间范围内输出,过长的计算时间会影响任务响应效率。本项目采用加权多目标与分层惩罚结合的策略,将各项指标通过权重系数组合为一个综合代价,同时对违反硬约束的路径施加高额惩罚,使不满足安全要求的候选个体在进化早期即被淘汰。权重的选择通过实验和任务需求分析进行调节,并可由遗传算法进行自适应优化。为降低计算成本,利用DNN和RNN建立代价近似模型,对复杂物理代价进行快速估计,使遗传算法在演化过程中无需每次调用耗时的精确仿真模型,只对高潜力个体进行精细评估。在MATLAB R2025b环境中,通过合理使用并行工具箱与向量化求解,可以显著减少遗传算法每代评估的实际运行时间,实现在普通计算平台上的高效规划。

项目模型架构

总体架构与数据流设计

整个GA-DNN-RNN无人机三维路径规划模型在逻辑上可以分为环境建模模块、路径编码与解码模块、代价评估模块、深度网络模块和遗传优化模块。环境建模模块负责构建三维空间中的地形、障碍物、禁飞区以及风险场,并为深度网络提供栅格化或连续形式的特征描述。路径编码与解码模块建立控制点或轨迹参数到实际三维路径的映射,使遗传算法在相对低维的编码空间中搜索,同时能够恢复到高采样密度的路径点序列,用于后续代价计算和可视化分析。代价评估模块整合来自DNN的静态环境代价预测和来自RNN的时序代价预测,结合物理能耗模型与安全约束检测,为每条候选路径返回一个综合适应度值。深度网络模块包括DNN和RNN两个子结构,DNN主要输入静态环境特征和路径局部形态,输出局部风险或单位长度代价;RNN则输入序列形式的路径节点及历史状态,输出整条路径的动态代价估计,如能耗随时间的累积变化或未来风险趋势。遗传优化模块将路径编码视作个体基因,在每一代中根据适应度执行选择、交叉和变异操作,生成新的路径方案,并通过代价评估模块更新适应度,直至收敛或达到最大迭代次数。这样的架构使各模块间既相互关联又相对独立,便于在MATLAB中逐步开发与调试,并可根据任务要求灵活扩展特定模块的能力。

环境建模与三维代价场构造

环境建模是三维路径规划的基础。通过将真实或虚拟环境表示为三维网格和连续地形函数,可以为DNN提供可学习的特征输入。基本原理是使用数字高程模型描述地形高度,使用若干几何体表示建筑物和固定障碍,将禁飞区表示为不允许通过的空间集合。进而,根据环境特征构造三维代价场,对不同空间位置赋予不同代价值,值越高代表风险越大、能耗越高或需要避免的区域。DNN的任务之一,就是学习从环境局部特征到代价值的映射,使在规划阶段可以快速查询任一点的代价近似值,而不必每次重新计算复杂的物理模型。此外,还可以引入风场和通信质量等额外字段,形成多通道三维特征场,作为DNN输入。RNN则通过时间维度上的路径序列输入,从过去的飞行状态中捕捉环境动态变化的影响。通过这种方式,环境建模不仅为遗传算法提供约束和代价评估数据,也为深度网络提供丰富的训练特征,使整体架构能够在模拟与真实环境之间进行迁移。

DNN模块的结构设计与功能定位

深度神经网络模块主要用于对静态环境与局部路径几何特征进行建模,输出例如局部风险评分、单位距离能耗估计、栅格化代价场的修正值等。其基本原理是通过多层非线性变换,将高维输入映射到低维输出,利用大量训练样本学习这一映射关系。在MATLAB中可以使用层图或layerGraph搭建DNN结构,典型结构包含若干全连接层、批量归一化层和激活函数层。网络的输入可以设计为局部环境特征向量,如路径点附近体素的高度、障碍密度、风速和安全区域指标等。通过训练,DNN将逐步学会在复杂环境下评估某一点或一小段路径的风险及成本。在GA-DNN-RNN框架中,DNN不仅参与训练阶段的代价预测,也可在遗传算法迭代过程中实时被调用,充当快速代价近似器,从而显著降低真实物理仿真代价计算带来的时间开销。网络参数的初始值和结构配置可以通过先验经验设定,再利用遗传算法微调部分超参数,如隐藏层神经元数量、学习率、正则化权重等,从而提高整体拟合精度和稳定性。

RNN模块的序列建模能力与角色

循环神经网络模块用于处理路径作为时序序列的属性。例如,一条路径由若干连续路径点组成,每个路径点具有位置、速度、姿态等属性,这一序列的演化决定了无人机的安全性和能耗。RNN利用内部记忆单元和状态反馈机制,在处理序列时能够将历史信息保留下来,在预测当前或未来输出时考虑先前的状态。典型结构包括LSTM或GRU单元,它们通过门控机制解决传统RNN中的梯度消失和梯度爆炸问题。在三维路径规划中,RNN可以输入路径点序列、环境特征序列以及当前飞行状态,输出对未来能量消耗、风场影响或安全风险的预测值。与DNN侧重局部空间特征不同,RNN强调时间连续性和长期依赖关系,从而对整个路径的动态表现做出评估。在遗传算法迭代过程中,RNN可以对每条候选路径进行快速时序模拟,估计其在真实执行过程中可能产生的累积代价。如此一来,路径规划不再仅仅依赖静态代价场,而是将时序效应考虑在内,使最终选择的路径更符合实际飞行过程中的综合表现。

GA与DNN-RNN耦合的优化机制

遗传算法在这一框架中承担全局搜索和结构优化的任务。其基本原理是将路径参数或网络超参数编码为染色体,通过选择、交叉和变异机制在种群中进行进化。适应度函数由DNN和RNN输出的代价估计以及硬约束惩罚共同构成,对每个个体进行打分。GA与DNN-RNN的耦合方式可以有两种主要形式。一种是路径级耦合,即遗传算法直接在路径编码空间中进行搜索,DNN和RNN被视为固定的代价评估器,仅提供代价评估,GA负责优化路径本身。另一种是模型级耦合,将部分网络结构或超参数作为遗传算法的优化对象,在训练阶段通过GA寻找更优的网络配置,提高网络的预测性能。项目中可同时采用这两种耦合方式,在前期利用GA优化网络结构,得到性能稳定的DNN和RNN;在规划阶段再使用GA在路径空间搜索,利用已训练好的网络进行快速代价评估。这样的双层耦合使得遗传算法既能发挥全局搜索优势,又能弥补深度学习在复杂损失面上可能陷入局部极小值的不足,从系统层面提升路径规划的整体性能和稳定性。

项目模型描述及代码示例

三维环境构建与地形生成示例
clear; clc; close all; % 清空工作区变量、命令窗口并关闭所有图窗,确保后续仿真环境干净
envSize = [100 100 50]; % 定义三维环境尺寸,x和y方向100个单位,z方向高度50个单位
[xGrid,yGrid] = meshgrid(0:dx:envSize(1),0:dy:envSize(2)); % 在水平平面上生成二维网格,用于构造地形高度场
baseHeight = 5; % 设定地形基础高度,避免出现完全平地场景
terrain = baseHeight + 8*peaks(size(xGrid,1)); % 使用peaks函数生成起伏地形,将其叠加到基础高度上模拟山丘地形
terrain = terrain - min(terrain(:)); % 将地形整体平移,使最低点为0高度,便于后续约束处理
terrain = min(terrain,envSize(3)-10); % 限制地形最高高度低于环境顶端,保留10个单位安全空间
numBuildings = 20; % 指定随机建筑物数量,用于模拟城市障碍环境
buildingCenters = rand(numBuildings,2).*envSize(1:2); % 在平面上随机生成建筑物中心位置
buildingHeights = 15 + 20*rand(numBuildings,1); % 随机生成建筑物高度,范围约15到35
obstacleMap = zeros(size(xGrid)); % 创建二维障碍物高度图,初始状态无障碍
for k = 1:numBuildings % 遍历每一个建筑物,依次叠加到障碍物图上
    cx = buildingCenters(k,1); % 读取当前建筑物中心x坐标
    cy = buildingCenters(k,2); % 读取当前建筑物中心y坐标
    sx = buildingSizes(k,1); % 读取当前建筑物在x方向尺寸
    sy = buildingSizes(k,2); % 读取当前建筑物在y方向尺寸
    h  = buildingHeights(k); % 读取当前建筑物高度
    mask = abs(xGrid-cx) <= sx/2 & abs(yGrid-cy) <= sy/2; % 通过矩形范围判断网格点是否落在建筑物平面投影内
end
terrainWithObs = max(terrain,obstacleMap); % 将自然地形和建筑障碍融合,得到最终地表高度图
goalPoint  = [95 95 30]; % 设定无人机终点坐标,位于右上角上空,保持高度一致便于对比
safetyMargin = 5; % 定义相对地表的安全裕度,确保飞行高度高于地形与建筑一定距离
figure; % 新建图窗用于三维地形可视化
plot3(goalPoint(1),goalPoint(2),goalPoint(3),'ro','MarkerSize',10,'LineWidth',2); % 在地形图上绘制终点标记,使用红色圆点表示
view(45,30); grid on; % 调整观察视角和开启网格,方便观察地形结构与高度变化
路径参数化与初始路径生成示例
numCtrlPts = 6; % 设定路径控制点数量,包括起点与终点在内,决定路径形状的灵活程度
dim = 3; % 每个控制点包含x、y、z三个坐标维度
ctrlPts = zeros(numCtrlPts,dim); % 创建控制点矩阵,初始为零,用于保存路径控制点坐标
ctrlPts(1,:) = startPoint; % 将第一个控制点设置为起点位置,保证路径起始点正确
ctrlPts(end,:) = goalPoint; % 将最后一个控制点设置为终点位置,保证路径终止点正确
for i = 2:numCtrlPts-1 % 对中间控制点进行随机初始化,避免所有控制点在一条直线
    alpha = (i-1)/(numCtrlPts-1); % 计算当前控制点在起点与终点之间的线性插值系数
    basePos = (1-alpha)*startPoint + alpha*goalPoint; % 根据插值系数获取中间控制点的大致位置
    randOffset = [randn*5,randn*5,randn*3]; % 为中间控制点引入随机偏移,使路径具有初始多样性
    ctrlPts(i,:) = basePos + randOffset; % 将插值位置与随机偏移叠加得到最终控制点位置
    ctrlPts(i,1) = min(max(ctrlPts(i,1),0),envSize(1)); % 对x坐标进行边界裁剪,确保控制点在环境范围内
    ctrlPts(i,2) = min(max(ctrlPts(i,2),0),envSize(2)); % 对y坐标进行边界裁剪,避免路径离开水平范围
    ctrlPts(i,3) = min(max(ctrlPts(i,3),safetyMargin),envSize(3)); % 对z坐标进行裁剪,保证高于地表安全裕度且不超过环境上界
end
tCtrl = linspace(0,1,numCtrlPts); % 在参数空间中为控制点分配归一化参数,用于样条插值
tQuery = linspace(0,1,200); % 设置查询参数序列,用于在路径上生成高分辨率采样点
xSpline = spline(tCtrl,ctrlPts(:,1),tQuery); % 对控制点x坐标进行三次样条插值,生成平滑x轨迹
ySpline = spline(tCtrl,ctrlPts(:,2),tQuery); % 对控制点y坐标进行三次样条插值,生成平滑y轨迹
pathInit = [xSpline(:),ySpline(:),zSpline(:)]; % 将插值结果组合为初始路径点序列,每行代表一个路径点
figure; % 新建图窗用于展示初始路径与地形的空间关系
surf(xGrid,yGrid,terrainWithObs,'EdgeColor','none'); % 再次绘制地形与障碍表面,提供背景环境
colormap(turbo); % 设置色图为turbo,保持与上一图一致的视觉风格
hold on; % 保持图形,叠加绘制路径与控制点
plot3(pathInit(:,1),pathInit(:,2),pathInit(:,3),'b-','LineWidth',2); % 绘制初始样条路径,以蓝色曲线表示
plot3(ctrlPts(:,1),ctrlPts(:,2),ctrlPts(:,3),'kx--','LineWidth',1.5); % 绘制控制点连线,以黑色虚线展示路径骨架
plot3(startPoint(1),startPoint(2),startPoint(3),'go','MarkerSize',8,'LineWidth',2); % 标记起点位置,使用绿色圆点
plot3(goalPoint(1),goalPoint(2),goalPoint(3),'ro','MarkerSize',8,'LineWidth',2); % 标记终点位置,使用红色圆点
xlabel('X'); ylabel('Y'); zlabel('Z'); % 设置三维坐标轴标签,便于识别方向
title('基于控制点样条插值的初始三维路径'); % 为图形添加描述,说明当前展示的是初始样条路径
DNN局部代价预测网络构建与训练示例
numSamples = 5000; % 设定用于训练DNN的样本数量,规模越大网络越容易学习复杂映射
localPatchSize = 5; % 设定局部高度补丁尺寸,将环境局部区域抽取为5x5的高度窗口
numFeatures = localPatchSize^2 + 3; % 输入特征维度为局部高度窗口展开加上路径点x、y、z坐标
Xtrain = zeros(numSamples,numFeatures); % 创建训练输入矩阵,每行对应一个样本的特征向量
Ytrain = zeros(numSamples,1); % 创建训练输出向量,每个样本对应一个局部代价值标签
for n = 1:numSamples % 遍历生成每一个训练样本
    px = rand*envSize(1); % 随机采样路径点x坐标,覆盖整个环境范围
    py = rand*envSize(2); % 随机采样路径点y坐标,与x一起确定平面位置
    ix = round(px/dx)+1; % 根据采样位置计算对应的网格索引x,索引从1开始
    iy = round(py/dy)+1; % 根据采样位置计算对应的网格索引y,用于从地形中抽取局部补丁
    ix = min(max(ix,3),size(terrainWithObs,2)-2); % 限制x索引在有效范围内,确保周围有足够补丁区域
    iy = min(max(iy,3),size(terrainWithObs,1)-2); % 限制y索引范围,避免提取局部窗口时越界
    patch = terrainWithObs(iy-2:iy+2,ix-2:ix+2); % 从地形与障碍融合高度图中提取5x5局部高度补丁
    groundHeight = terrainWithObs(iy,ix); % 获取当前平面网格点的地表高度,包含地形与建筑物
    relHeight = pz - groundHeight; % 计算路径点相对于地表的相对高度,作为安全性的重要指标
    risk = max(0,safetyMargin-relHeight); % 若相对高度低于安全裕度,则计算风险惩罚,否则风险为零
    Ytrain(n) = 1 + 0.1*norm([px-envSize(1)/2,py-envSize(2)/2])/max(envSize(1:2)) + 5*risk; % 综合平面位置与安全风险构造代价标签
end
Xtrain = normalize(Xtrain); % 对输入特征进行归一化处理,提升DNN训练稳定性与收敛速度
layersDNN = [ ...
    featureInputLayer(numFeatures,'Name','input'); % 定义特征输入层,接收numFeatures维的连续特征
    fullyConnectedLayer(64,'Name','fc1'); % 第一全连接层,包含64个神经元,用于初步特征提取
    reluLayer('Name','relu1'); % ReLU激活层,引入非线性以增强表达能力
    fullyConnectedLayer(64,'Name','fc2'); % 第二全连接层,进一步抽象高阶特征
    reluLayer('Name','relu2'); % 第二个ReLU层,保持模型非线性结构
    fullyConnectedLayer(32,'Name','fc3'); % 第三全连接层,降低特征维度并压缩信息
    reluLayer('Name','relu3'); % 第三个ReLU层,增强深度网络的非线性表示能力
    fullyConnectedLayer(1,'Name','fc_out'); % 输出层全连接至单一神经元,对应局部代价预测值
optionsDNN = trainingOptions('adam', ... % 使用Adam优化器,具有自适应学习率和动量
    'MiniBatchSize',128, ... % 设置每个小批量样本数为128,加速训练并稳定梯度
    'InitialLearnRate',1e-3, ... % 设置初始学习率为1e-3,适度的步长有利于收敛
    'Shuffle','every-epoch', ... % 每个训练轮次对样本重新打乱,防止顺序性影响训练
netDNN = trainNetwork(Xtrain,Ytrain,layersDNN,optionsDNN); % 使用构建好的网络结构与训练选项对训练数据进行网络训练
RNN时序代价预测网络构建与训练示例
numSeq = 800; % 设定RNN训练用路径序列数量,提供足够多样的时序样本
seqLength = 40; % 每条路径序列包含离散路径点数量,代表飞行过程长度
featureDim = 4; % 每个时刻的特征维度,包含x、y、z以及相对高度信息
XSeq = cell(numSeq,1); % 创建单元数组存放每个样本的输入序列特征
YSeq = cell(numSeq,1); % 创建单元数组存放每个样本的输出序列代价值
for n = 1:numSeq % 遍历生成每条训练路径序列
    tLine = linspace(0,1,seqLength); % 在0到1之间生成等距参数,用于直线路径插值
    xLine = startPoint(1) + (goalPoint(1)-startPoint(1))*tLine; % 生成直线路径的x坐标序列
    yLine = startPoint(2) + (goalPoint(2)-startPoint(2))*tLine; % 生成直线路径的y坐标序列
    zLine = startPoint(3) + (goalPoint(3)-startPoint(3))*tLine; % 生成直线路径的z坐标序列
    windPerturb = 3*randn(1,seqLength); % 生成模拟风场扰动序列,影响路径高度
    zLine = zLine + windPerturb; % 将风场扰动叠加到高度轨迹,制造更复杂的时序特征
    zLine = max(zLine,safetyMargin); % 确保所有时刻高度不低于安全裕度,避免明显不合理情况
    featSeq = zeros(featureDim,seqLength); % 创建当前样本的特征矩阵,尺寸为特征维度乘以序列长度
    costSeq = zeros(1,seqLength); % 创建当前样本的代价值序列,记录每一时刻的累积代价
    for t = 1:seqLength % 遍历每个时间步,构造特征并计算代价
        px = xLine(t); % 当前时刻路径点x坐标
        ix = round(px/dx)+1; % 将x坐标映射为地形网格索引
        ix = min(max(ix,1),size(terrainWithObs,2)); % 限制x索引在有效范围内,防止越界
        groundHeight = terrainWithObs(iy,ix); % 提取当前网格点地表高度
        relHeight = pz - groundHeight; % 计算当前点相对地表高度
        featSeq(:,t) = [px;py;pz;relHeight]; % 将当前点的空间坐标与相对高度组成特征向量
        riskCost = max(0,safetyMargin-relHeight)*10; % 若相对高度低于安全裕度,施加额外风险惩罚
        costSeq(t) = baseCost + riskCost; % 当前时刻代价为基础代价与风险代价之和
    end
    XSeq{n} = featSeq; % 保存当前样本的特征序列到输入单元数组中
    YSeq{n} = costSeq; % 保存当前样本的代价序列到输出单元数组中
end
numHidden = 64; % 设定LSTM隐藏单元数量,决定网络记忆容量与表达能力
layersRNN = [ ...
    sequenceInputLayer(featureDim,'Name','seq_in'); % 序列输入层,输入每个时间步的特征向量
    lstmLayer(numHidden,'OutputMode','sequence','Name','lstm1'); % LSTM层,输出整个序列的隐藏状态序列
    fullyConnectedLayer(32,'Name','fc_rnn'); % 全连接层,将LSTM输出映射到较低维度
    reluLayer('Name','relu_rnn'); % ReLU激活层,引入非线性增强拟合能力
    fullyConnectedLayer(1,'Name','fc_rnn_out'); % 最终全连接层生成单一代价输出
optionsRNN = trainingOptions('adam', ... % 使用Adam优化器训练RNN,适合处理非平稳序列
    'MaxEpochs',15, ... % 最大训练轮数设为15,兼顾训练时间与模型性能
    'MiniBatchSize',16, ... % 使用16的批量大小,以平衡内存占用与训练稳定性
    'Verbose',false); % 关闭详细训练信息输出,保持命令窗口整洁
netRNN = trainNetwork(XSeq,YSeq,layersRNN,optionsRNN); % 调用trainNetwork训练构建好的RNN,用于时序代价预测
适应度函数与路径代价评估示例
function cost = evaluatePathCost(ctrlGene,netDNN,netRNN,terrainWithObs,safetyMargin,envSize,dx,dy) % 定义路径代价评估函数,输入为控制点基因、网络与环境参数返回适应度
numCtrlPts = numel(ctrlGene)/3; % 根据基因长度推回控制点数量,每三个基因构成一个控制点
ctrlPts = reshape(ctrlGene,[],3); % 将一维基因数组重塑为控制点矩阵,每行对应一个控制点
ctrlPts(1,:) = max(min(ctrlPts(1,:),envSize),[0 0 safetyMargin]); % 将第一个控制点裁剪到合法空间范围内,保证安全高度
tCtrl = linspace(0,1,numCtrlPts); % 为控制点分配归一化参数,用于样条插值
tQuery = linspace(0,1,100); % 设定路径采样参数数量,越多路径越精细
xSpline = spline(tCtrl,ctrlPts(:,1),tQuery); % 根据控制点x坐标生成平滑样条路径
zSpline = spline(tCtrl,ctrlPts(:,3),tQuery); % 根据控制点z坐标生成平滑高度路径
segVec = diff(path,1,1); % 计算相邻路径点之间的向量差,表示小路径段
segLen = sqrt(sum(segVec.^2,2)); % 计算每一段路径的欧氏长度,作为距离代价基础
totalLength = sum(segLen); % 将所有段长度相加得到路径总长度
localPatchSize = 5; % 指定局部高度补丁尺寸,与DNN训练时保持一致
halfPatch = (localPatchSize-1)/2; % 计算补丁半径,用于索引局部区域
numPts = size(path,1); % 记录这一条路径上离散点的数量
Xlocal = zeros(numPts,localPatchSize^2+3); % 创建局部特征输入矩阵,用于调用DNN预测代价
    px = path(i,1); % 当前路径点x坐标
    pz = path(i,3); % 当前路径点z坐标
    ix = round(px/dx)+1; % 将x坐标映射到地形网格索引
    iy = round(py/dy)+1; % 将y坐标映射到地形网格索引
    ix = min(max(ix,1+halfPatch),size(terrainWithObs,2)-halfPatch); % 调整x索引范围,确保局部补丁完全包含在地形中
    iy = min(max(iy,1+halfPatch),size(terrainWithObs,1)-halfPatch); % 调整y索引范围,避免从地形矩阵外取值
    patch = terrainWithObs(iy-halfPatch:iy+halfPatch,ix-halfPatch:ix+halfPatch); % 根据索引提取局部高度补丁
    feat = [patch(:)' px py pz]; % 将补丁展开并附加当前空间坐标,构成局部输入特征
    Xlocal(i,:) = feat; % 将特征写入特征矩阵中对应行
end
Xlocal = normalize(Xlocal); % 对局部特征进行归一化,与DNN训练阶段保持一致处理
localCost = localCost(:); % 将DNN输出转换为列向量,便于后续加权累积
relHeights = zeros(numPts,1); % 创建相对高度向量,用于构造RNN输入特征
for i = 1:numPts % 再次遍历路径点,计算相对地表高度
    px = path(i,1); % 当前点x坐标
    py = path(i,2); % 当前点y坐标
    ix = round(px/dx)+1; % 计算对应的地形网格索引x
    iy = round(py/dy)+1; % 计算对应的地形网格索引y
    ix = min(max(ix,1),size(terrainWithObs,2)); % 限制x索引在合法范围内
    iy = min(max(iy,1),size(terrainWithObs,1)); % 限制y索引在合法范围内
    groundHeight = terrainWithObs(iy,ix); % 读取当前网格点的地表高度
end
featSeq = featSeq'; % 转置为特征维度乘以时间长度的矩阵,以匹配sequenceInputLayer要求
seqCost = predict(netRNN,featSeq); % 使用训练好的RNN对整条路径的时序代价进行预测
seqCost = seqCost(:); % 将RNN输出转换为列向量,表示每个时间步的代价估计
localWeight  = 0.5; % 局部代价权重,用于平衡DNN预测代价与其他部分
seqWeight    = 0.5; % 时序代价权重,控制RNN预测代价在适应度中的权重
penalty = 0; % 初始化违反约束的惩罚项,初始为零表示无惩罚
if any(relHeights < safetyMargin) % 若任何路径点相对高度低于安全裕度则触发惩罚
    penalty = penalty + 1e4; % 增加一个较大的惩罚值,强制遗传算法避开不安全路径
end
for i = 1:numPts % 遍历所有路径点检查是否穿越地面或障碍物内部
        penalty = penalty + 1e5; % 施加更大的惩罚,确保遗传算法几乎不会选择此类路径
cost = lengthWeight*totalLength + localWeight*sum(localCost.*[segLen;segLen(end)]) + seqWeight*sum(seqCost) + penalty; % 将长度、局部代价、时序代价与惩罚组合成总成本
遗传算法配置与路径优化主程序示例
numCtrlPtsGA = 6; % 遗传算法搜索使用的控制点数量,与样条路径控制点一致
ub = zeros(1,numVars); % 初始化决策变量上界,将在后续逐维设置
for k = 1:numCtrlPtsGA % 遍历每一个控制点,设置坐标上界
    baseIdx = (k-1)*3; % 计算当前控制点对应决策变量起始索引
    ub(baseIdx+2) = envSize(2); % y坐标上界设为环境y方向最大值
    ub(baseIdx+3) = envSize(3); % z坐标上界设为环境高度最大值
    lb(baseIdx+3) = safetyMargin; % z坐标下界设为安全裕度,避免控制点过低
end
lb(1:3) = startPoint; % 强制第一个控制点下界与起点一致,固定路径起点位置
ub(1:3) = startPoint; % 强制第一个控制点上界也为起点,使遗传算法不能改变起点
ub(end-2:end) = goalPoint; % 强制最后一个控制点上界为终点,确保路径终止点正确
fitnessFcn = @(gene)evaluatePathCost(gene,netDNN,netRNN,terrainWithObs,safetyMargin,envSize,dx,dy); % 将路径代价评估函数包装为适应度函数句柄
optionsGA = optimoptions('ga', ... % 调用ga函数的选项构造器,并设置主要参数
    'PopulationSize',60, ... % 设定种群规模为60个个体,以平衡多样性与计算量
    'MaxGenerations',40, ... % 设置最大进化代数为40,控制算法迭代次数
    'CrossoverFraction',0.8, ... % 设置交叉概率为0.8,使大部分个体参与基因重组
    'MutationFcn',@mutationadaptfeasible, ... % 使用自适应可行域变异函数,提高处理约束能力
    'Display','iter'); % 设置每代迭代过程在命令窗口显示简要信息
[bestGene,bestCost,exitflag,outputGA] = ga(fitnessFcn,numVars,[],[],[],[],lb,ub,[],optionsGA); % 调用遗传算法执行全局优化,返回最优基因及相关信息
numCtrlPtsOpt = numel(bestGene)/3; % 根据最优基因长度计算控制点数量
ctrlPtsOpt = reshape(bestGene,[],3); % 将最优基因重塑为控制点矩阵
tCtrlOpt = linspace(0,1,numCtrlPtsOpt); % 为优化后的控制点生成归一化参数序列
tQueryOpt = linspace(0,1,200); % 设置较高分辨率采样参数,用于生成最终平滑路径
xOpt = spline(tCtrlOpt,ctrlPtsOpt(:,1),tQueryOpt); % 对最优控制点x坐标进行样条插值
yOpt = spline(tCtrlOpt,ctrlPtsOpt(:,2),tQueryOpt); % 对最优控制点y坐标进行样条插值
zOpt = spline(tCtrlOpt,ctrlPtsOpt(:,3),tQueryOpt); % 对最优控制点z坐标进行样条插值
figure; % 新建图窗展示优化后的路径结果
surf(xGrid,yGrid,terrainWithObs,'EdgeColor','none'); % 绘制三维地形与障碍背景
hold on; % 保持当前图形,叠加绘制路径
plot3(pathOpt(:,1),pathOpt(:,2),pathOpt(:,3),'r-','LineWidth',2.5); % 绘制GA-DNN-RNN优化后的路径轨迹,以红色粗线表示
plot3(startPoint(1),startPoint(2),startPoint(3),'go','MarkerSize',10,'LineWidth',2); % 标记起点位置,便于识别路径起始
plot3(goalPoint(1),goalPoint(2),goalPoint(3),'bo','MarkerSize',10,'LineWidth',2); % 标记终点位置,以蓝色圆点区分于起点
xlabel('X'); ylabel('Y'); zlabel('Z'); % 设置坐标轴标签,确保三维方向清晰
title(sprintf('GA-DNN-RNN优化三维路径  总成本 %.2f',bestCost)); % 在标题中显示优化后路径的总成本,方便对比性能
view(45,30); grid on; % 调整观察视角与网格显示,使路径与地形关系更直观
segVecOpt = diff(pathOpt,1,1); % 计算优化路径相邻点之间的向量差,用于分析局部几何特性
totalLenOpt = sum(segLenOpt); % 计算优化路径总长度,用于性能评价
relHeightOpt = zeros(size(pathOpt,1),1); % 创建相对高度向量,用于分析路径安全裕度
for i = 1:size(pathOpt,1) % 遍历优化路径上的每一点,计算相对高度
    px = pathOpt(i,1); % 当前路径点x坐标
    py = pathOpt(i,2); % 当前路径点y坐标
    pz = pathOpt(i,3); % 当前路径点z坐标
    ix = round(px/dx)+1; % 将x坐标映射为地形网格索引
    iy = round(py/dy)+1; % 将y坐标映射为地形网格索引
    ix = min(max(ix,1),size(terrainWithObs,2)); % 确保x索引不越界
    iy = min(max(iy,1),size(terrainWithObs,1)); % 确保y索引不越界
    relHeightOpt(i) = pz - groundHeight; % 计算相对地表高度并写入数组
end
figure; % 新建图窗展示优化路径相对高度变化
hold on; % 保留当前图形,叠加绘制安全裕度线
yline(safetyMargin,'r--','LineWidth',1.5); % 绘制安全裕度参考线,表示安全高度阈值
xlabel('路径点索引'); ylabel('相对地表高度'); % 设置坐标轴标签,说明纵轴含义
title('优化路径沿程相对地表高度变化'); % 为图形添加标题,帮助理解安全裕度分布
figure; % 新建图窗分析路径局部曲率与长度分布
plot(1:numel(segLenOpt),segLenOpt,'k-','LineWidth',1.5); % 绘制每一段路径长度,用于观察局部变化
xlabel('路径段索引'); ylabel('段长'); % 设置坐标轴标签,解释图像含义
grid on; % 开启网格,辅助分析局部长度变化的趋势

三维环境构建与地形生成示例

clear; clc; close all; % 清空工作区变量、命令窗口并关闭所有图窗,确保后续仿真环境干净
envSize = [100 100 50]; % 定义三维环境尺寸,x和y方向100个单位,z方向高度50个单位
[xGrid,yGrid] = meshgrid(0:dx:envSize(1),0:dy:envSize(2)); % 在水平平面上生成二维网格,用于构造地形高度场
baseHeight = 5; % 设定地形基础高度,避免出现完全平地场景
terrain = baseHeight + 8*peaks(size(xGrid,1)); % 使用peaks函数生成起伏地形,将其叠加到基础高度上模拟山丘地形
terrain = terrain - min(terrain(:)); % 将地形整体平移,使最低点为0高度,便于后续约束处理
terrain = min(terrain,envSize(3)-10); % 限制地形最高高度低于环境顶端,保留10个单位安全空间
numBuildings = 20; % 指定随机建筑物数量,用于模拟城市障碍环境
buildingCenters = rand(numBuildings,2).*envSize(1:2); % 在平面上随机生成建筑物中心位置
buildingHeights = 15 + 20*rand(numBuildings,1); % 随机生成建筑物高度,范围约15到35
obstacleMap = zeros(size(xGrid)); % 创建二维障碍物高度图,初始状态无障碍
for k = 1:numBuildings % 遍历每一个建筑物,依次叠加到障碍物图上
    cx = buildingCenters(k,1); % 读取当前建筑物中心x坐标
    cy = buildingCenters(k,2); % 读取当前建筑物中心y坐标
    sx = buildingSizes(k,1); % 读取当前建筑物在x方向尺寸
    sy = buildingSizes(k,2); % 读取当前建筑物在y方向尺寸
    h  = buildingHeights(k); % 读取当前建筑物高度
    mask = abs(xGrid-cx) <= sx/2 & abs(yGrid-cy) <= sy/2; % 通过矩形范围判断网格点是否落在建筑物平面投影内
end
terrainWithObs = max(terrain,obstacleMap); % 将自然地形和建筑障碍融合,得到最终地表高度图
goalPoint  = [95 95 30]; % 设定无人机终点坐标,位于右上角上空,保持高度一致便于对比
safetyMargin = 5; % 定义相对地表的安全裕度,确保飞行高度高于地形与建筑一定距离
figure; % 新建图窗用于三维地形可视化
plot3(goalPoint(1),goalPoint(2),goalPoint(3),'ro','MarkerSize',10,'LineWidth',2); % 在地形图上绘制终点标记,使用红色圆点表示
view(45,30); grid on; % 调整观察视角和开启网格,方便观察地形结构与高度变化

路径参数化与初始路径生成示例

numCtrlPts = 6; % 设定路径控制点数量,包括起点与终点在内,决定路径形状的灵活程度
dim = 3; % 每个控制点包含x、y、z三个坐标维度
ctrlPts = zeros(numCtrlPts,dim); % 创建控制点矩阵,初始为零,用于保存路径控制点坐标
ctrlPts(1,:) = startPoint; % 将第一个控制点设置为起点位置,保证路径起始点正确
ctrlPts(end,:) = goalPoint; % 将最后一个控制点设置为终点位置,保证路径终止点正确
for i = 2:numCtrlPts-1 % 对中间控制点进行随机初始化,避免所有控制点在一条直线
    alpha = (i-1)/(numCtrlPts-1); % 计算当前控制点在起点与终点之间的线性插值系数
    basePos = (1-alpha)*startPoint + alpha*goalPoint; % 根据插值系数获取中间控制点的大致位置
    randOffset = [randn*5,randn*5,randn*3]; % 为中间控制点引入随机偏移,使路径具有初始多样性
    ctrlPts(i,:) = basePos + randOffset; % 将插值位置与随机偏移叠加得到最终控制点位置
    ctrlPts(i,1) = min(max(ctrlPts(i,1),0),envSize(1)); % 对x坐标进行边界裁剪,确保控制点在环境范围内
    ctrlPts(i,2) = min(max(ctrlPts(i,2),0),envSize(2)); % 对y坐标进行边界裁剪,避免路径离开水平范围
    ctrlPts(i,3) = min(max(ctrlPts(i,3),safetyMargin),envSize(3)); % 对z坐标进行裁剪,保证高于地表安全裕度且不超过环境上界
end
tCtrl = linspace(0,1,numCtrlPts); % 在参数空间中为控制点分配归一化参数,用于样条插值
tQuery = linspace(0,1,200); % 设置查询参数序列,用于在路径上生成高分辨率采样点
xSpline = spline(tCtrl,ctrlPts(:,1),tQuery); % 对控制点x坐标进行三次样条插值,生成平滑x轨迹
ySpline = spline(tCtrl,ctrlPts(:,2),tQuery); % 对控制点y坐标进行三次样条插值,生成平滑y轨迹
pathInit = [xSpline(:),ySpline(:),zSpline(:)]; % 将插值结果组合为初始路径点序列,每行代表一个路径点
figure; % 新建图窗用于展示初始路径与地形的空间关系
surf(xGrid,yGrid,terrainWithObs,'EdgeColor','none'); % 再次绘制地形与障碍表面,提供背景环境
colormap(turbo); % 设置色图为turbo,保持与上一图一致的视觉风格
hold on; % 保持图形,叠加绘制路径与控制点
plot3(pathInit(:,1),pathInit(:,2),pathInit(:,3),'b-','LineWidth',2); % 绘制初始样条路径,以蓝色曲线表示
plot3(ctrlPts(:,1),ctrlPts(:,2),ctrlPts(:,3),'kx--','LineWidth',1.5); % 绘制控制点连线,以黑色虚线展示路径骨架
plot3(startPoint(1),startPoint(2),startPoint(3),'go','MarkerSize',8,'LineWidth',2); % 标记起点位置,使用绿色圆点
plot3(goalPoint(1),goalPoint(2),goalPoint(3),'ro','MarkerSize',8,'LineWidth',2); % 标记终点位置,使用红色圆点
xlabel('X'); ylabel('Y'); zlabel('Z'); % 设置三维坐标轴标签,便于识别方向
title('基于控制点样条插值的初始三维路径'); % 为图形添加描述,说明当前展示的是初始样条路径

DNN局部代价预测网络构建与训练示例

numSamples = 5000; % 设定用于训练DNN的样本数量,规模越大网络越容易学习复杂映射
localPatchSize = 5; % 设定局部高度补丁尺寸,将环境局部区域抽取为5x5的高度窗口
numFeatures = localPatchSize^2 + 3; % 输入特征维度为局部高度窗口展开加上路径点x、y、z坐标
Xtrain = zeros(numSamples,numFeatures); % 创建训练输入矩阵,每行对应一个样本的特征向量
Ytrain = zeros(numSamples,1); % 创建训练输出向量,每个样本对应一个局部代价值标签
for n = 1:numSamples % 遍历生成每一个训练样本
    px = rand*envSize(1); % 随机采样路径点x坐标,覆盖整个环境范围
    py = rand*envSize(2); % 随机采样路径点y坐标,与x一起确定平面位置
    ix = round(px/dx)+1; % 根据采样位置计算对应的网格索引x,索引从1开始
    iy = round(py/dy)+1; % 根据采样位置计算对应的网格索引y,用于从地形中抽取局部补丁
    ix = min(max(ix,3),size(terrainWithObs,2)-2); % 限制x索引在有效范围内,确保周围有足够补丁区域
    iy = min(max(iy,3),size(terrainWithObs,1)-2); % 限制y索引范围,避免提取局部窗口时越界
    patch = terrainWithObs(iy-2:iy+2,ix-2:ix+2); % 从地形与障碍融合高度图中提取5x5局部高度补丁
    groundHeight = terrainWithObs(iy,ix); % 获取当前平面网格点的地表高度,包含地形与建筑物
    relHeight = pz - groundHeight; % 计算路径点相对于地表的相对高度,作为安全性的重要指标
    risk = max(0,safetyMargin-relHeight); % 若相对高度低于安全裕度,则计算风险惩罚,否则风险为零
    Ytrain(n) = 1 + 0.1*norm([px-envSize(1)/2,py-envSize(2)/2])/max(envSize(1:2)) + 5*risk; % 综合平面位置与安全风险构造代价标签
end
Xtrain = normalize(Xtrain); % 对输入特征进行归一化处理,提升DNN训练稳定性与收敛速度
layersDNN = [ ...
    featureInputLayer(numFeatures,'Name','input'); % 定义特征输入层,接收numFeatures维的连续特征
    fullyConnectedLayer(64,'Name','fc1'); % 第一全连接层,包含64个神经元,用于初步特征提取
    reluLayer('Name','relu1'); % ReLU激活层,引入非线性以增强表达能力
    fullyConnectedLayer(64,'Name','fc2'); % 第二全连接层,进一步抽象高阶特征
    reluLayer('Name','relu2'); % 第二个ReLU层,保持模型非线性结构
    fullyConnectedLayer(32,'Name','fc3'); % 第三全连接层,降低特征维度并压缩信息
    reluLayer('Name','relu3'); % 第三个ReLU层,增强深度网络的非线性表示能力
    fullyConnectedLayer(1,'Name','fc_out'); % 输出层全连接至单一神经元,对应局部代价预测值
optionsDNN = trainingOptions('adam', ... % 使用Adam优化器,具有自适应学习率和动量
    'MiniBatchSize',128, ... % 设置每个小批量样本数为128,加速训练并稳定梯度
    'InitialLearnRate',1e-3, ... % 设置初始学习率为1e-3,适度的步长有利于收敛
    'Shuffle','every-epoch', ... % 每个训练轮次对样本重新打乱,防止顺序性影响训练
netDNN = trainNetwork(Xtrain,Ytrain,layersDNN,optionsDNN); % 使用构建好的网络结构与训练选项对训练数据进行网络训练

RNN时序代价预测网络构建与训练示例

numSeq = 800; % 设定RNN训练用路径序列数量,提供足够多样的时序样本
seqLength = 40; % 每条路径序列包含离散路径点数量,代表飞行过程长度
featureDim = 4; % 每个时刻的特征维度,包含x、y、z以及相对高度信息
XSeq = cell(numSeq,1); % 创建单元数组存放每个样本的输入序列特征
YSeq = cell(numSeq,1); % 创建单元数组存放每个样本的输出序列代价值
for n = 1:numSeq % 遍历生成每条训练路径序列
    tLine = linspace(0,1,seqLength); % 在0到1之间生成等距参数,用于直线路径插值
    xLine = startPoint(1) + (goalPoint(1)-startPoint(1))*tLine; % 生成直线路径的x坐标序列
    yLine = startPoint(2) + (goalPoint(2)-startPoint(2))*tLine; % 生成直线路径的y坐标序列
    zLine = startPoint(3) + (goalPoint(3)-startPoint(3))*tLine; % 生成直线路径的z坐标序列
    windPerturb = 3*randn(1,seqLength); % 生成模拟风场扰动序列,影响路径高度
    zLine = zLine + windPerturb; % 将风场扰动叠加到高度轨迹,制造更复杂的时序特征
    zLine = max(zLine,safetyMargin); % 确保所有时刻高度不低于安全裕度,避免明显不合理情况
    featSeq = zeros(featureDim,seqLength); % 创建当前样本的特征矩阵,尺寸为特征维度乘以序列长度
    costSeq = zeros(1,seqLength); % 创建当前样本的代价值序列,记录每一时刻的累积代价
    for t = 1:seqLength % 遍历每个时间步,构造特征并计算代价
        px = xLine(t); % 当前时刻路径点x坐标
        ix = round(px/dx)+1; % 将x坐标映射为地形网格索引
        ix = min(max(ix,1),size(terrainWithObs,2)); % 限制x索引在有效范围内,防止越界
        groundHeight = terrainWithObs(iy,ix); % 提取当前网格点地表高度
        relHeight = pz - groundHeight; % 计算当前点相对地表高度
        featSeq(:,t) = [px;py;pz;relHeight]; % 将当前点的空间坐标与相对高度组成特征向量
        riskCost = max(0,safetyMargin-relHeight)*10; % 若相对高度低于安全裕度,施加额外风险惩罚
        costSeq(t) = baseCost + riskCost; % 当前时刻代价为基础代价与风险代价之和
    end
    XSeq{n} = featSeq; % 保存当前样本的特征序列到输入单元数组中
    YSeq{n} = costSeq; % 保存当前样本的代价序列到输出单元数组中
end
numHidden = 64; % 设定LSTM隐藏单元数量,决定网络记忆容量与表达能力
layersRNN = [ ...
    sequenceInputLayer(featureDim,'Name','seq_in'); % 序列输入层,输入每个时间步的特征向量
    lstmLayer(numHidden,'OutputMode','sequence','Name','lstm1'); % LSTM层,输出整个序列的隐藏状态序列
    fullyConnectedLayer(32,'Name','fc_rnn'); % 全连接层,将LSTM输出映射到较低维度
    reluLayer('Name','relu_rnn'); % ReLU激活层,引入非线性增强拟合能力
    fullyConnectedLayer(1,'Name','fc_rnn_out'); % 最终全连接层生成单一代价输出
optionsRNN = trainingOptions('adam', ... % 使用Adam优化器训练RNN,适合处理非平稳序列
    'MaxEpochs',15, ... % 最大训练轮数设为15,兼顾训练时间与模型性能
    'MiniBatchSize',16, ... % 使用16的批量大小,以平衡内存占用与训练稳定性
    'Verbose',false); % 关闭详细训练信息输出,保持命令窗口整洁
netRNN = trainNetwork(XSeq,YSeq,layersRNN,optionsRNN); % 调用trainNetwork训练构建好的RNN,用于时序代价预测

适应度函数与路径代价评估示例

function cost = evaluatePathCost(ctrlGene,netDNN,netRNN,terrainWithObs,safetyMargin,envSize,dx,dy) % 定义路径代价评估函数,输入为控制点基因、网络与环境参数返回适应度
numCtrlPts = numel(ctrlGene)/3; % 根据基因长度推回控制点数量,每三个基因构成一个控制点
ctrlPts = reshape(ctrlGene,[],3); % 将一维基因数组重塑为控制点矩阵,每行对应一个控制点
ctrlPts(1,:) = max(min(ctrlPts(1,:),envSize),[0 0 safetyMargin]); % 将第一个控制点裁剪到合法空间范围内,保证安全高度
tCtrl = linspace(0,1,numCtrlPts); % 为控制点分配归一化参数,用于样条插值
tQuery = linspace(0,1,100); % 设定路径采样参数数量,越多路径越精细
xSpline = spline(tCtrl,ctrlPts(:,1),tQuery); % 根据控制点x坐标生成平滑样条路径
zSpline = spline(tCtrl,ctrlPts(:,3),tQuery); % 根据控制点z坐标生成平滑高度路径
segVec = diff(path,1,1); % 计算相邻路径点之间的向量差,表示小路径段
segLen = sqrt(sum(segVec.^2,2)); % 计算每一段路径的欧氏长度,作为距离代价基础
totalLength = sum(segLen); % 将所有段长度相加得到路径总长度
localPatchSize = 5; % 指定局部高度补丁尺寸,与DNN训练时保持一致
halfPatch = (localPatchSize-1)/2; % 计算补丁半径,用于索引局部区域
numPts = size(path,1); % 记录这一条路径上离散点的数量
Xlocal = zeros(numPts,localPatchSize^2+3); % 创建局部特征输入矩阵,用于调用DNN预测代价
    px = path(i,1); % 当前路径点x坐标
    pz = path(i,3); % 当前路径点z坐标
    ix = round(px/dx)+1; % 将x坐标映射到地形网格索引
    iy = round(py/dy)+1; % 将y坐标映射到地形网格索引
    ix = min(max(ix,1+halfPatch),size(terrainWithObs,2)-halfPatch); % 调整x索引范围,确保局部补丁完全包含在地形中
    iy = min(max(iy,1+halfPatch),size(terrainWithObs,1)-halfPatch); % 调整y索引范围,避免从地形矩阵外取值
    patch = terrainWithObs(iy-halfPatch:iy+halfPatch,ix-halfPatch:ix+halfPatch); % 根据索引提取局部高度补丁
    feat = [patch(:)' px py pz]; % 将补丁展开并附加当前空间坐标,构成局部输入特征
    Xlocal(i,:) = feat; % 将特征写入特征矩阵中对应行
end
Xlocal = normalize(Xlocal); % 对局部特征进行归一化,与DNN训练阶段保持一致处理
localCost = localCost(:); % 将DNN输出转换为列向量,便于后续加权累积
relHeights = zeros(numPts,1); % 创建相对高度向量,用于构造RNN输入特征
for i = 1:numPts % 再次遍历路径点,计算相对地表高度
    px = path(i,1); % 当前点x坐标
    py = path(i,2); % 当前点y坐标
    ix = round(px/dx)+1; % 计算对应的地形网格索引x
    iy = round(py/dy)+1; % 计算对应的地形网格索引y
    ix = min(max(ix,1),size(terrainWithObs,2)); % 限制x索引在合法范围内
    iy = min(max(iy,1),size(terrainWithObs,1)); % 限制y索引在合法范围内
    groundHeight = terrainWithObs(iy,ix); % 读取当前网格点的地表高度
end
featSeq = featSeq'; % 转置为特征维度乘以时间长度的矩阵,以匹配sequenceInputLayer要求
seqCost = predict(netRNN,featSeq); % 使用训练好的RNN对整条路径的时序代价进行预测
seqCost = seqCost(:); % 将RNN输出转换为列向量,表示每个时间步的代价估计
localWeight  = 0.5; % 局部代价权重,用于平衡DNN预测代价与其他部分
seqWeight    = 0.5; % 时序代价权重,控制RNN预测代价在适应度中的权重
penalty = 0; % 初始化违反约束的惩罚项,初始为零表示无惩罚
if any(relHeights < safetyMargin) % 若任何路径点相对高度低于安全裕度则触发惩罚
    penalty = penalty + 1e4; % 增加一个较大的惩罚值,强制遗传算法避开不安全路径
end
for i = 1:numPts % 遍历所有路径点检查是否穿越地面或障碍物内部
        penalty = penalty + 1e5; % 施加更大的惩罚,确保遗传算法几乎不会选择此类路径
cost = lengthWeight*totalLength + localWeight*sum(localCost.*[segLen;segLen(end)]) + seqWeight*sum(seqCost) + penalty; % 将长度、局部代价、时序代价与惩罚组合成总成本

遗传算法配置与路径优化主程序示例

numCtrlPtsGA = 6; % 遗传算法搜索使用的控制点数量,与样条路径控制点一致
ub = zeros(1,numVars); % 初始化决策变量上界,将在后续逐维设置
for k = 1:numCtrlPtsGA % 遍历每一个控制点,设置坐标上界
    baseIdx = (k-1)*3; % 计算当前控制点对应决策变量起始索引
    ub(baseIdx+2) = envSize(2); % y坐标上界设为环境y方向最大值
    ub(baseIdx+3) = envSize(3); % z坐标上界设为环境高度最大值
    lb(baseIdx+3) = safetyMargin; % z坐标下界设为安全裕度,避免控制点过低
end
lb(1:3) = startPoint; % 强制第一个控制点下界与起点一致,固定路径起点位置
ub(1:3) = startPoint; % 强制第一个控制点上界也为起点,使遗传算法不能改变起点
ub(end-2:end) = goalPoint; % 强制最后一个控制点上界为终点,确保路径终止点正确
fitnessFcn = @(gene)evaluatePathCost(gene,netDNN,netRNN,terrainWithObs,safetyMargin,envSize,dx,dy); % 将路径代价评估函数包装为适应度函数句柄
optionsGA = optimoptions('ga', ... % 调用ga函数的选项构造器,并设置主要参数
    'PopulationSize',60, ... % 设定种群规模为60个个体,以平衡多样性与计算量
    'MaxGenerations',40, ... % 设置最大进化代数为40,控制算法迭代次数
    'CrossoverFraction',0.8, ... % 设置交叉概率为0.8,使大部分个体参与基因重组
    'MutationFcn',@mutationadaptfeasible, ... % 使用自适应可行域变异函数,提高处理约束能力
    'Display','iter'); % 设置每代迭代过程在命令窗口显示简要信息
[bestGene,bestCost,exitflag,outputGA] = ga(fitnessFcn,numVars,[],[],[],[],lb,ub,[],optionsGA); % 调用遗传算法执行全局优化,返回最优基因及相关信息
numCtrlPtsOpt = numel(bestGene)/3; % 根据最优基因长度计算控制点数量
ctrlPtsOpt = reshape(bestGene,[],3); % 将最优基因重塑为控制点矩阵
tCtrlOpt = linspace(0,1,numCtrlPtsOpt); % 为优化后的控制点生成归一化参数序列
tQueryOpt = linspace(0,1,200); % 设置较高分辨率采样参数,用于生成最终平滑路径
xOpt = spline(tCtrlOpt,ctrlPtsOpt(:,1),tQueryOpt); % 对最优控制点x坐标进行样条插值
yOpt = spline(tCtrlOpt,ctrlPtsOpt(:,2),tQueryOpt); % 对最优控制点y坐标进行样条插值
zOpt = spline(tCtrlOpt,ctrlPtsOpt(:,3),tQueryOpt); % 对最优控制点z坐标进行样条插值
figure; % 新建图窗展示优化后的路径结果
surf(xGrid,yGrid,terrainWithObs,'EdgeColor','none'); % 绘制三维地形与障碍背景
hold on; % 保持当前图形,叠加绘制路径
plot3(pathOpt(:,1),pathOpt(:,2),pathOpt(:,3),'r-','LineWidth',2.5); % 绘制GA-DNN-RNN优化后的路径轨迹,以红色粗线表示
plot3(startPoint(1),startPoint(2),startPoint(3),'go','MarkerSize',10,'LineWidth',2); % 标记起点位置,便于识别路径起始
plot3(goalPoint(1),goalPoint(2),goalPoint(3),'bo','MarkerSize',10,'LineWidth',2); % 标记终点位置,以蓝色圆点区分于起点
xlabel('X'); ylabel('Y'); zlabel('Z'); % 设置坐标轴标签,确保三维方向清晰
title(sprintf('GA-DNN-RNN优化三维路径  总成本 %.2f',bestCost)); % 在标题中显示优化后路径的总成本,方便对比性能
view(45,30); grid on; % 调整观察视角与网格显示,使路径与地形关系更直观
segVecOpt = diff(pathOpt,1,1); % 计算优化路径相邻点之间的向量差,用于分析局部几何特性
totalLenOpt = sum(segLenOpt); % 计算优化路径总长度,用于性能评价
relHeightOpt = zeros(size(pathOpt,1),1); % 创建相对高度向量,用于分析路径安全裕度
for i = 1:size(pathOpt,1) % 遍历优化路径上的每一点,计算相对高度
    px = pathOpt(i,1); % 当前路径点x坐标
    py = pathOpt(i,2); % 当前路径点y坐标
    pz = pathOpt(i,3); % 当前路径点z坐标
    ix = round(px/dx)+1; % 将x坐标映射为地形网格索引
    iy = round(py/dy)+1; % 将y坐标映射为地形网格索引
    ix = min(max(ix,1),size(terrainWithObs,2)); % 确保x索引不越界
    iy = min(max(iy,1),size(terrainWithObs,1)); % 确保y索引不越界
    relHeightOpt(i) = pz - groundHeight; % 计算相对地表高度并写入数组
end
figure; % 新建图窗展示优化路径相对高度变化
hold on; % 保留当前图形,叠加绘制安全裕度线
yline(safetyMargin,'r--','LineWidth',1.5); % 绘制安全裕度参考线,表示安全高度阈值
xlabel('路径点索引'); ylabel('相对地表高度'); % 设置坐标轴标签,说明纵轴含义
title('优化路径沿程相对地表高度变化'); % 为图形添加标题,帮助理解安全裕度分布
figure; % 新建图窗分析路径局部曲率与长度分布
plot(1:numel(segLenOpt),segLenOpt,'k-','LineWidth',1.5); % 绘制每一段路径长度,用于观察局部变化
xlabel('路径段索引'); ylabel('段长'); % 设置坐标轴标签,解释图像含义
grid on; % 开启网格,辅助分析局部长度变化的趋势

更多详细内容请访问

http://无人机MATLAB实现基于GA-DNN-RNN遗传算法(GA)结合深度神经网络(DNN)与循环神经网络(RNN)进行无人机三维路径规划的详细项目实例(含完整的程序,GUI设计和代码详解)资源-CSDN下载  https://download.csdn.net/download/xiaoxingkongyuxi/92784867

 https://download.csdn.net/download/xiaoxingkongyuxi/92784867

http:// https://download.csdn.net/download/xiaoxingkongyuxi/92784867

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐