尧图精选

基于RBF神经网络补偿的无人机姿态自适应控制仿真

🕒 发布时间:2026/9/6 14:02:36 📁 来源:尧图网络
简介针对四旋翼无人机姿态控制中模型不完整、参数不确定和外界扰动等难题这份 PDF 论文提出了一种基于 RBF 神经网络的无人机姿态自适应控制方法。内容从四旋翼动力学建模入手详细阐述了利用 RBF 神经网络在线学习模型不确定项与外界扰动的原理并基于反步法设计包含反馈控制和神经网络控制的自适应控制器同时给出了网络权值自适应律利用李雅普诺夫方法对闭环系统稳定性进行了严格证明。文中还提供了仿真结果分析展示了在较大扰动情况下误差快速收敛、系统具备较好鲁棒性和自适应性的控制效果可供相关课题直接参考。资源为单文件 PDF大小约 3.65MB适合自动化、控制工程及无人机方向的研究生和工程师学习使用已有 269 人学习下载。 无人机飞得好不好说到底就是一个字调。但调PID这件事做过飞控的人都知道有多折磨。尤其到了姿态环P值给大了抖D值给小了飘悬停刚稳住风一吹又开始荡。我前前后后调过好几架四旋翼从纯手调到自动调参工具都试过始终绕不开一个问题控制器参数是固定的但无人机在空中遇到的环境、载重、重心变化却是随时在变的。所以当我决定把神经网络引入姿态控制时思路很简单——与其花几个晚上反复试凑增益不如让控制器自己学会补偿那些说不清、算不准的非线性扰动。这篇文章就记录了我用MATLAB/Simulink做“基于神经网络的无人机姿态自适应控制仿真”的完整过程包括数学模型、控制器结构、代码实现和踩坑实录。不管是正在做毕业设计的自动化学生还是想给飞控加点智能算法的爱好者都可以直接参考这套框架。1. 为什么传统PID在无人机姿态控制上不够用1.1 四旋翼姿态控制到底难在哪先说清楚被控对象。四旋翼是一个典型的欠驱动、强耦合、非线性系统四个电机的转速变化同时影响滚转、俯仰、偏航和总升力任何一个通道的动作都会牵扯到另外几个通道。实际飞行中气动阻尼、陀螺力矩、旋翼尾流扰动都在实时变化而且变化的规律很难精确建模。更麻烦的是不确定性。比如我用的机架是仿F450结构装上电池、相机、云台之后质量和转动惯量已经和出厂参数不一样了。换一块更重的电池重心哪怕偏移几毫米悬停时就需要一个恒定的姿态偏置来补偿。这种情况下一组固定增益的姿态PID是难以同时满足“动态响应快”和“稳态不震荡”这两个要求的。1.2 传统控制的三个死穴第一个死穴是模型依赖。LQR、反步法、滑模控制都需要相对精确的模型参数但这些参数在实际飞行中变化很大。第二个死穴是固定增益。PID三个增益一整定好就不再变遇到大风、挂载投掷这类突变工况要么反应太慢要么超调振荡。第三个死穴是难以处理强非线性。四旋翼的动力学本身包含三角函数、耦合项、执行器饱和传统的线性化方法在小角度假设下勉强可用一旦做敏捷机动就原形毕露。1.3 神经网络在这里扮演什么角色神经网络在姿态控制里的定位不是完全替代PID而是做一个“在线补偿器”。核心思路是基础控制仍由PID或PD完成保证系统稳定神经网络则负责估计系统的未建模动态、参数摄动和外部扰动并把补偿量叠加上去。这样既保留经典控制的可靠性又获得自适应能力。我选用的是RBF径向基函数网络原因是它结构简单、局部逼近能力强、在线计算量小非常适合部署在飞控这种算力受限的嵌入式环境里。相比需要大量数据离线训练的深度网络RBF网络可以在仿真过程中实时更新权值真正做到“边飞边学”。2. 被控对象建模四旋翼的数学模型和参数设置2.1 坐标系和欧拉角约定仿真第一步是建立无人机的数学模型。我采用最常见的“机体坐标系B 地面坐标系E”双坐标系方案地面坐标系用来描述位置和姿态参考方向机体坐标系固定在机身上随无人机一起运动。两者之间的转换通过ZYX顺序的欧拉角实现——先偏航yaw绕Z轴再俯仰pitch绕Y轴最后滚转roll绕X轴。姿态角的角速度关系和很多人理解的不太一样欧拉角的导数并不直接等于机体角速度。真正的运动学方程是roll_dot p sin(roll)*tan(pitch)*q cos(roll)*tan(pitch)*r pitch_dot cos(roll)*q - sin(roll)*r yaw_dot sin(roll)/cos(pitch)*q cos(roll)/cos(pitch)*r这里 p、q、r 是机体坐标系下的三轴角速度。我在仿真里没有做小角度近似而是用完整的非线性方程为的就是让控制器在大姿态角下也能被验证。2.2 刚体动力学方程姿态动力学方程用牛顿-欧拉法推导核心是机体坐标系下的力矩平衡I * omega_dot -omega × (I * omega) M_prop M_dist展开后就是三个轴的角加速度方程p_dot ( (Iy-Iz)*q*r Mx ) / Ix q_dot ( (Iz-Ix)*p*r My ) / Iy r_dot ( (Ix-Iy)*p*q Mz ) / Iz其中 Mx、My、Mz 是作用在机体上的总力矩包括电机转速差产生的控制力矩和气动阻力矩。-omega × (I*omega) 这一项就是陀螺力矩很多初学者会忽略它但在快速偏航或翻滚时它的影响非常明显——如果控制器没有足够的鲁棒性这个交叉耦合项会让姿态响应出现肉眼可见的“串扰”。2.3 模型参数怎么设置我仿真里用的参数参考了一台1.5kg级四旋翼的实测值参数数值说明质量 m1.5 kg含电池负载滚转惯量 Ix0.012 kg·m²绕X轴俯仰惯量 Iy0.012 kg·m²绕Y轴偏航惯量 Iz0.022 kg·m²绕Z轴力臂长度 l0.225 m机臂长度升力系数 cT1.5e-5 N/(rad/s)²螺旋桨阻力系数 cQ2.0e-7 N·m/(rad/s)²螺旋桨电机到升力和力矩的关系按标准十字布局计算F_total cT * (w1² w2² w3² w4²) Mx l*cT*(w1² - w3²) My l*cT*(w2² - w4²) Mz cQ*(w1² - w2² w3² - w4²)通过这套模型我就能在Simulink里搭建一个“虚拟无人机”用它来验证控制器在不同扰动下的表现。3. 神经网络自适应控制器设计3.1 控制器总体架构整个姿态控制采用的是内外环串级结构内环是角速度环快回路外环是姿态角环慢回路。外环PID生成期望角速度内环负责实际跟踪。神经网络不单独做控制器而是并联在角速度环PID的输出端叠加一个补偿力矩。这个架构最大的好处是就算神经网络输出异常底层的PID仍然能维持系统基本稳定安全性有兜底。这是我当时在笔记里画的信号流向按这个理解就不会乱姿态角给定 —— 姿态角PID —— 角速度给定 —— 角速度PID —— [叠加神经网络补偿] —— 电机混控 —— 四旋翼动力学 —— 姿态角输出 ↑ 角速度误差、误差导数注入RBF网络 —— 网络输出补偿力矩3.2 RBF网络结构我用的RBF网络是最简洁的一种结构。输入层取两个关键状态量——角速度误差 e 和角速度误差变化率 ec隐藏层取5个高斯径向基节点输出层是1个补偿力矩。高斯径向基函数定义为phi_j(x) exp( -||x - c_j||² / (2*sigma_j²) )其中 c_j 是第j个基函数的中心sigma_j 是宽度。这一步有讲究基函数中心和宽度的选取直接决定网络能在哪个输入范围产生有效响应。我把中心均匀设置在 [-2, 2] × [-2, 2] 的网格上宽度取0.8这样覆盖了大部分实际飞行的角速度误差范围。中心太密会增加计算量太疏则局部逼近性能下降5个节点对单通道补偿来说是够用的。网络输出就是简单的加权和M_nn sum( w_j * phi_j(x) )w_j 是输出层权值需要通过自适应律实时更新。3.3 自适应律推导为什么权值这样更新这里如果不解释清楚整个设计和“玄学调参”没区别。核心思想是构造一个李雅普诺夫函数让权值更新律保证系统状态收敛。定义角速度跟踪误差为 e omega_d - omega并构造滑模面 s e c*integral(e)。控制目标是让 s 趋于零。对滑模面求导并把四旋翼动力学方程代入整理后可以得到一个形如s_dot -k*s (f_uncertain - W*phi(x))的形式其中 f_uncertain 是模型不确定项Wphi(x) 是RBF网络对它的估计。如果能做到 f_uncertain ≈ Wphi(x)那么误差项就被抵消了系统退化为线性稳定的形式 s_dot -k*s。我构造李雅普诺夫候选函数V 0.5*s² 0.5/gamma * sum(w_tilde_j²)其中 w_tilde_j w_j* - w_j 是权值估计误差gamma 是学习率。对 V 求导选择合适的权值更新律使 V_dot ≤ 0就能证明跟踪误差和权值误差是有界的。最终的权值更新律非常简单w_j_dot gamma * s * phi_j(x)这就是经典的梯度下降形式的在线修正规则。在Simulink里实现时我用一个积分器对 w_j_dot 做积分就得到每一时刻的权值。学习率 gamma 我取0.05太大权值震荡剧烈太小自适应速度跟不上。3.4 为什么不用标准BP网络和深度网络这个坑我替大家踩过了。最开始我用的是标准BP神经网络vanilla RNN的思路把角速度误差序列作为输入用时间反向传播更新权值。结果在纯仿真里表现尚可但仔细分析后发现问题BP反向传播每一层都要计算梯度在线运行时每一控制周期都要做一遍矩阵运算计算量是RBF的几十倍更重要的是BP网络是全局逼近任何输入的微小变化都会导致所有神经元权值一起调整在线学习的稳定性很差。深度网络就更不用说了。姿态控制是一个毫秒级的实时任务每个控制周期一般只有1~10毫秒深度网络的前向推理和反向传播根本跑不满这个时间约束。RBF网络虽然结构简单但足够逼近连续非线性函数而且是局部响应——输入在某个基函数中心附近时只有对应的少数节点被激活权值更新互不干扰在线学习的稳定性和收敛速度都好得多。同理我也不推荐在姿态内环用LSTM这类时序网络。虽然它们能建模时间相关性但计算开销和实现复杂度都是这个场景无法接受的。把时序记忆放在外环规划层面可以放在内环控制层面就是给飞控增加不必要的负担。4. 仿真搭建与核心代码实现4.1 仿真环境选型的取舍仿真平台我选的是MATLAB/Simulink主要原因是控制算法验证方便、自带丰富的积分器和信号可视化工具。Simulink的S-Function块可以嵌入自定义的C语言或MATLAB代码用来描述神经网络的在线更新特别顺手。为了仿真我装的是MATLAB R2021a这个版本对S-Function的支持已经很成熟。如果不方便用MATLAB也可以用Python替代用numpy自己写四旋翼动力学用scipy.integrate求解微分方程控制器部分直接面向对象实现。我下文会给出两个版本的核心代码。4.2 MATLAB脚本四旋翼动力学与RBF控制器先贴一段最核心的MATLAB脚本结构。动力学部分用一个函数文件描述返回姿态角速度和角加速度function [dot_state] quad_dynamics(state, M, params) % state: [roll; pitch; yaw; p; q; r] % M: 控制力矩向量 [Mx; My; Mz] % params: 结构体包含惯性参数 phi state(1); theta state(2); psi state(3); p state(4); q state(5); r state(6); % 运动学方程欧拉角变化率 dot_phi p sin(phi)*tan(theta)*q cos(phi)*tan(theta)*r; dot_theta cos(phi)*q - sin(phi)*r; dot_psi sin(phi)/cos(theta)*q cos(phi)/cos(theta)*r; % 动力学方程角加速度 Ix params.Ix; Iy params.Iy; Iz params.Iz; dot_p ((Iy-Iz)*q*r M(1)) / Ix; dot_q ((Iz-Ix)*p*r M(2)) / Iy; dot_r ((Ix-Iy)*p*q M(3)) / Iz; dot_state [dot_phi; dot_theta; dot_psi; dot_p; dot_q; dot_r]; endRBF神经网络控制器的核心是权值更新。这段代码放在Simulink的S-Function里每个采样周期调用一次function [M_nn, w_new] rbf_controller(e, ec, w, x) % 输入e角速度误差, ec误差变化率, 上一时刻权值, 基函数参数 % 输出神经网络补偿力矩, 更新后的权值 % 基函数中心和宽度 c [-2 -1 0 1 2; -2 -1 0 1 2]; % 二维中心网格 sigma 0.8; % 计算高斯径向基输出 phi zeros(1, 5); for j 1:5 phi(j) exp(-((e-c(1,j))^2 (ec-c(2,j))^2) / (2*sigma^2)); end % 权值更新律 w_j_dot gamma * s * phi_j gamma 0.05; s e 0.5 * integral_ec; % 滑模面 w_dot gamma * s * phi; w_new w w_dot * dt; % 输出补偿力矩 M_nn w_new * phi; end4.3 Simulink集成要点在Simulink里搭建时模块连线并不复杂。我用三个积分器串联表示姿态角和角速度状态第一个积分器输出姿态角输入是角速度第二个积分器输出角速度输入是角加速度第三个积分器用来计算误差积分项。S-Function块接收角速度误差和误差变化率输出补偿力矩给混控模块。比较值得注意的两个细节一是基本采样时间我设的是0.002秒即500Hz控制频率模拟真实飞控Pixhawk默认姿态环就是这个频率。二是积分器初值第一次跑仿真时我初始姿态角设置了[5°, -3°, 0°]相当于给控制器一个初始偏差测试它能不能快速拉回水平。这里的响应曲线最能说明问题初始偏差归零越快控制器的瞬态性能越好。4.4 Python版本如果不用MATLAB在Gazebo里跑过仿真的人都知道ROS和Gazebo的环境配置有时候比写控制算法还折磨人。这里我分享一个轻量级的Python仿真方案更利于理解控制算法的本质对于只关注算法原理验证的场景是完全足够的。核心代码如下import numpy as np from scipy.integrate import solve_ivp class RBFController: def __init__(self, n_centers5, gamma0.05, dim2): self.gamma gamma self.sigma 0.8 centers np.linspace(-2, 2, n_centers) self.c np.array(np.meshgrid(centers, centers)).T.reshape(-1, dim) self.w np.zeros(len(self.c)) def phi(self, x): # 高斯径向基函数 d np.linalg.norm(self.c - x, axis1) return np.exp(-d**2 / (2 * self.sigma**2)) def update(self, e, ec, s): phis self.phi(np.array([e, ec])) self.w self.gamma * s * phis return np.dot(self.w, phis) # 补偿力矩 # 主仿真循环 def simulate(): params {Ix: 0.012, Iy: 0.012, Iz: 0.022} state np.array([0.05, -0.02, 0, 0, 0, 0]) # 初始小角度偏移 rbf RBFController() dt 0.002 for t in range(10000): # 这里根据姿态角和角速度误差调用rbf.update()再叠加PID输出 # 用欧拉积分更新state passPython方案的好处是能直接在脚本里打日志、画曲线、做批量参数扫描特别适合论文里的参数对比实验。缺点是没有Simulink那种可视化搭模型的方式被控对象和控制器之间的连接需要自己在代码里捏合。最开始跑的时候我建议先用Simulink搭一遍对信号流有整体感觉再迁移到Python做大规模实验。5. 结果分析自适应效果与踩坑实录5.1 测试工况怎么设计才有说服力仿真只设定悬停一个工况是不够的控制器到底自适应在哪里需要用多种工况来验证。我设计了四组实验阶跃给定给一个30°的俯仰角阶跃考察跟踪速度和超调量。风扰力矩在2秒时注入一个8 m/s的持续阵风扰动力矩看看控制器能否顶住。参数突变在第5秒把质量从1.5kg突加到1.8kg模拟挂载载荷的变化。重心偏移给机体添加一个恒定的偏置力矩模拟重心偏离几何中心的情况。每一组都有对照组即不带神经网络、只有PID的版本。同一套PID参数跑两组对照差异一目了然。5.2 实测结果神经网络补偿到底带来什么先说结论效果最惊艳的不是阶跃响应PID本来就能跟踪得不错而是在抗扰和参数突变这两项。参数突变实验里不带神经网络的PID重新爬升到稳态需要约3秒期间俯仰角出现了约8°的偏差。带RBF补偿的网络则在0.2秒内就补偿掉了大部分偏置稳态误差从2.1°降到了0.3°以内。原因是神经网络通过在线权值更新快速辨识出了额外的重力力矩需要并在输出端加了一个恒定的前馈补偿量。这个补偿量本质上是“学会”了新的挂载重量不需要重新整定PID增益。重心偏移实验更有意思。给无人机的滚转轴叠加强制扰动力矩后PID控制器的反应是“对抗”——它会维持一个恒定的静差或者说需要积分项慢慢吃掉偏差。RBF网络则直接把重心偏移的等效力矩学了出来权值稳定后控制器输出里多了一个恒定的偏置项恰好等于重心偏移产生的力矩。这就是“补偿”和“对抗”的本质区别神经网络学会的是“原因”PID只能在“结果”层面纠偏。5.3 仿真过程中踩过的坑排在首位的坑是基函数中心范围设置不当。我第一次设中心范围是[-1, 1]结果大角度机动时输入超出覆盖范围径向基输出近乎为零网络直接“失明”了补偿量消失PID独自扛下所有。改成[-2, 2]之后问题消失。这是RBF网络特有的问题网络的表达能力只在中心覆盖的区间内有效输入一旦超出覆盖范围输出就截断为零。基函数覆盖范围必须大于最大误差范围没有捷径。第二个坑是学习率过大导致的权值振荡。我把 gamma 设成0.3时前200步网络权值剧烈震荡补偿力矩像噪声一样叠加在控制输出上差点以为控制器发散。后来把学习率降到0.05并用滑模面s代替纯误差e做驱动项震荡立刻缓解。这里的原理不复杂学习率大权值对误差的响应快但如果误差本身还在振荡权值就会跟着振荡形成正反馈恶性循环。第三个坑比较隐蔽Simulink代数环。S-Function的当前输出依赖于当前输入而输入又由输出决定时Simulink会报代数环错误。我的解决办法是在S-Function输出后加一个单位延迟块unit delay虽然理论分析时差了一个采样周期但实际控制频率500Hz下一个周期的延迟对系统稳定性的影响可以忽略。这个坑在纯代码仿真里不存在只在Simulink里遇到。第四个坑关于代码生成部署。仿真跑通后我曾想过把控制器迁移到Pixhawk真机上。但MATLAB Coder生成的C代码默认只用单精度浮点RBF高斯计算里的exp函数在Cortex-M4上开销不小一个控制周期根本算不完。后来我用查表法替代实时的exp计算才勉强压缩到1ms以内。如果打算最终上真机建议从一开始就把计算量控制住比如固定基函数中心后预先计算好高斯函数查找表。6. 关于这个系统的设计和扩展方向6.1 整体设计复盘回顾整个仿真项目值得肯定的是分层控制架构和“PID保底 RBF补偿”的组合方式。这种设计的好处不言而喻神经网络部分即使失效系统也不至于完全失控这在工程上是极其重要的保险机制。整个系统的设计逻辑是先确定控制目标然后建立被控对象的非线性模型再选择能够在线学习不确定项的网络结构最后用仿真验证各种工况下的表现。每一步都有清晰的动机而不是拍脑袋堆砌算法。我最初的方案里也考虑过直接套用完全神经网络控制器——即让网络直接输出全部控制力矩。第一版仿真就发现网络初始权值为零时无人机根本飞不起来需要很长的预训练时间。而“PID 自适应补偿”的方案初始阶段PID保证基本飞行能力网络可以在飞行过程中从零开始逐渐学习两者配合默契几乎没有冷启动问题。6.2 后续在飞控上的扩展思路在整个项目的收尾阶段我仔细思考了这套算法的扩展空间。目前RBF网络只能补偿每个轴独立的力矩偏差轴间耦合还没有建模。复杂机动时滚转和俯仰之间的交叉耦合依然明显下一步可以用多维输入把p*q耦合项一起送入网络学习理论上能进一步减小动态误差。从控制角度现在神经网络补偿的是“控制力矩”层面的不确定项还没有触及“参考模型”层面的自适应。如果改用模型参考自适应控制结构让网络直接调整到期望闭环动态的误差那就能针对不同任务的敏捷性需求在线调整控制带宽这是目前PID加固定补偿方案做不到的。在部署方面如果要做真机验证把Simulink模型通过Embedded Coder生成C代码、部署到Pixhawk飞行控制器是通用的路线。需要注意的是一个控制周期内RBF网络的5个径向基函数求值再加上PID计算在STM32F4这类主控上的耗时已经比较可观要么降低控制频率到250Hz要么减少基函数的数量。6.3 给想复现这个项目的人的建议根据我做这个仿真的全程经验给准备复现的读者三点建议。第一先跑通纯PID对照版本观测记录最基本的姿态响应再叠加RBF模块。直接上完整系统会分不清问题出在控制器设计还是网络调参。第二把所有参数写到一个配置文件中参数扫描时批量跑比手动改Simulink块参数高效得多。仿真中我每次改一组参数就要另存一份模型文件管理起来非常混乱后来干脆用脚本统一修改m文件中的参数并调sim函数才从重复劳动里解脱出来。第三记录每一组实验的完整数据包括权值轨迹、控制力矩、姿态误差曲线这些数据对写论文和答辩非常重要。仿真完随手导出成mat文件或csv比事后补做实验省时间得多。我至今还记得第一次看到权值轨迹稳定收敛时的场景俯仰角被强风拉偏6°BP补偿力矩迅速顶上去姿态在不到一秒钟内回到水平而PID对照组还在0.5°误差附近挣扎。那一瞬间你会直观感受到自适应控制的真正价值——它不是调出一个更好的参数而是让系统有了自我纠正的能力。这种能力在纯仿真中已经足够令人兴奋如果有一天跑在真机上飞行器的适应性和鲁棒性又会上一个台阶。希望这篇文章能帮你绕过我踩过的坑在仿真的基础上走得更远。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →