拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

神经网络自适应滑模控制:旋翼姿态抗扰与抖振抑制实战

神经网络自适应滑模控制:旋翼姿态抗扰与抖振抑制实战

简介:这份PDF文献面向无人机控制、非线性系统与智能算法方向的研究生及科研人员,聚焦四旋翼飞行器在未建模动态与外部未知扰动下的姿态控制难题。资源为单篇学术论文,压缩包内仅含1个PDF文件,大小约1.19MB,便于在电脑或移动端直接阅读与引用。论文以径向基函数神经网络在线补偿系统未建模部分,结合滑模控制增强对外部阵风扰动的鲁棒性,并给出闭环稳定性的严格理论证明,最后通过MATLAB/SIMULINK数值仿真验证算法在扰动条件下仍能保证渐近收敛。读者可从中获取神经网络与滑模控制融合的完整推导思路、姿态动力学建模方法及仿真验证流程,对撰写相关论文或开展工程实践具有参考价值。目前已有208人学习。

1. 神经网络自适应滑模做旋翼姿态控制:为什么纯滑模一到阵风就抖成筛子

旋翼飞行器姿态控制这件事,做过的人都知道,纯 PID 在室内悬停能飞,一出门遇到阵风、负载变化、电池电压掉下来,姿态就开始飘。滑模控制(Sliding Mode Control)本来是冲着鲁棒性去的,理论上只要切换增益够大,扰动再猛也能把状态摁回滑模面。但真机上跑起来你会发现另一个问题:抖振。切换项那一下高频来回切,电机跟着抖,桨叶跟着颤,飞控日志里角速度曲线像锯齿一样。

神经网络自适应滑模的思路,就是拿一个前馈神经网络去在线估计系统里的不确定项和外部扰动,把滑模切换增益从「拍脑袋给大」变成「按需给」,抖振自然就压下来了。这套方案适合谁?适合已经能把旋翼姿态动力学写成状态方程、手上有 MATLAB/Simulink 环境、想从纯滑模往自适应方向走一步的飞控工程师。它不要求你先把神经网络理论啃透,但要求你能看懂 Lyapunov 稳定性证明的基本套路,否则调参就是玄学。

这篇笔记按「动力学建模 → 滑模面设计 → 神经网络自适应律 → MATLAB 实现 → 避坑 → 进阶验证」的顺序推,每一步都给可复现的代码和参数。你照着搭一遍,至少能跑出一个比纯滑模抖振更小的姿态跟踪曲线。

2. 旋翼姿态动力学与滑模面:从非线性模型到可编程状态方程

2.1 为什么姿态环要用四元数而不是欧拉角

旋翼飞行器姿态动力学在机体坐标系下写,角速度动态是刚体转动方程,姿态运动学用四元数描述可以避免万向节死锁。很多论文为了推导方便用欧拉角,但你在 MATLAB 里做仿真时如果滚转接近 ±90°,欧拉角表示会出奇异点,仿真直接崩。常见做法是姿态运动学用四元数,角速度环用机体轴角速度,控制输出映射到电机转速。

姿态动力学简化形式:

J * ω_dot = -ω × (J * ω) + τ + d

其中 J 是转动惯量矩阵,ω 是机体角速度,τ 是控制力矩,d 是总扰动(含模型不确定性和外部风扰)。这个 d 就是神经网络要估计的对象。

四元数运动学:

q_dot = 0.5 * q ⊗ [0; ω]

⊗ 是四元数乘法。你在代码里不需要手写四元数乘法,MATLAB Aerospace Toolbox 有quatmultiply,但如果你不想依赖工具箱,自己写一个 20 行的函数也够用。

2.2 滑模面设计:线性滑模面够不够用

姿态控制一般用线性滑模面:

s = e_ω + Λ * e_q

e_q 是四元数姿态误差(取矢量部分),e_ω 是角速度误差,Λ 是正定对角阵。Λ 越大,姿态误差收敛越快,但太大会放大噪声。我一般从 Λ = diag(2, 2, 1.5) 起步,滚转和俯仰给大一点,偏航给小一点,因为偏航通道惯量大、响应慢。

滑模面确定后,控制律分两部分:

τ = τ_eq + τ_sw

τ_eq 是等效控制,抵消已知名义模型项;τ_sw 是切换控制,用符号函数或饱和函数。纯滑模的 τ_sw 增益固定,神经网络自适应滑模就是让这个增益或整个不确定项估计由神经网络在线输出。

提示:滑模面参数 Λ 和切换增益是两套参数,调参时先固定 Λ 调切换增益,再回头微调 Λ,不要同时动。

2.3 把动力学写成 MATLAB 可用的状态方程

下面这段代码把姿态动力学和运动学封装成一个 ODE 函数,供ode45调用。参数用的是一个 1.5 kg 级四旋翼的典型值,你可以替换成自己机型的实测惯量。

function dq = quad_attitude_dyn(t, q, J, tau, d) % q = [qw; qx; qy; qz; wx; wy; wz] % J: 3x3 转动惯量矩阵 % tau: 3x1 控制力矩 % d: 3x1 扰动 qw = q(1); qx = q(2); qy = q(3); qz = q(4); w = q(5:7); % 四元数运动学 Omega = [0, -w(1), -w(2), -w(3); w(1), 0, w(3), -w(2); w(2), -w(3), 0, w(1); w(3), w(2), -w(1), 0]; q_dot = 0.5 * Omega * [qw; qx; qy; qz]; % 角速度动力学 w_dot = J \ (-cross(w, J*w) + tau + d); dq = [q_dot; w_dot]; end

逻辑说明:四元数部分用矩阵形式写运动学,避免手写乘法出错;角速度部分直接解J \ (...),比求逆数值更稳。参数 J 对四旋翼典型值可以取diag([0.02, 0.02, 0.04]),单位 kg·m²。扰动 d 在仿真里先用正弦叠加模拟阵风,后面神经网络要估计的就是它。

注意:ode45对刚性系统可能步长很小,仿真慢。如果 J 各轴差异大,改用ode15s。

3. 神经网络自适应律:用前馈网络在线估计不确定项

3.1 为什么选前馈神经网络而不是 RNN 或 LSTM

姿态控制的不确定项主要是气动参数变化、负载偏移、风扰,这些量的时间尺度在几十到几百毫秒,前馈网络(BP 网络)单步推理就够,不需要循环结构。RNN 和 LSTM 适合处理时序依赖强的任务,但在这里会引入额外状态和延迟,反而让稳定性证明变复杂。常见做法是三层前馈网络:输入层取滑模面和角速度误差,隐层 7 到 15 个节点,输出层 3 个节点对应三轴扰动估计。

隐层激活函数用 sigmoid 或 tanh,输出层线性。权值更新律从 Lyapunov 函数推出来,保证权值有界。

3.2 自适应律的推导思路与代码映射

Lyapunov 函数取:

V = 0.5 * s' * s + 0.5 * tr(W_tilde' * Γ^{-1} * W_tilde)

对 V 求导,令含扰动估计误差的项被网络输出抵消,剩下的项用切换控制压制,就能得到权值更新律:

W_dot = Γ * φ(s) * s'

Γ 是学习率矩阵,φ(s) 是隐层输出。这个式子落到代码里就是每次积分步更新一次权值。

function [tau, W_new] = nn_adaptive_smc(q, q_d, W, params) % q: 当前状态 [qw;qx;qy;qz;wx;wy;wz] % q_d: 期望四元数 [qw;qx;qy;qz] % W: 当前网络权值 % params: 参数结构体 % 姿态误差四元数 q_curr = q(1:4); q_err = quatmultiply(quatinv(q_d'), q_curr'); e_q = q_err(2:4)'; % 取矢量部分 % 角速度误差 w = q(5:7); w_d = zeros(3,1); % 悬停期望角速度为零 e_w = w - w_d; % 滑模面 Lambda = params.Lambda; s = e_w + Lambda * e_q; % 神经网络前向 V = params.V; % 输入层到隐层权值 phi = tanh(V * [e_q; e_w]); d_hat = W * phi; % 扰动估计 % 等效控制(名义模型) J = params.J; tau_eq = cross(w, J*w) + J * (-Lambda * e_w); % 切换控制 eta = params.eta; tau_sw = -eta * sat(s / params.phi_b); % 总控制力矩 tau = tau_eq - J * d_hat + tau_sw; % 权值更新 Gamma = params.Gamma; W_new = W + params.dt * (Gamma * (s * phi')); end function y = sat(x) y = min(max(x, -1), 1); end

逻辑说明:quatmultiply和quatinv来自 Aerospace Toolbox,没有工具箱就自己写。sat函数替代符号函数,边界层厚度phi_b决定抖振抑制程度。权值更新用欧拉积分,步长dt要和仿真步长一致。

参数说明:学习率 Γ 取diag([50, 50, 30])起步,太大权值震荡,太小估计跟不上扰动。隐层节点数 9 个,输入 6 维(姿态误差 3 + 角速度误差 3),输出 3 维。切换增益 η 取diag([0.5, 0.5, 0.3]),比纯滑模小一个量级,因为神经网络已经承担了大部分扰动补偿。

提示:权值初始化不要全零,隐层权值用0.1 * randn初始化,输出层权值全零,这样初始扰动估计为零,不会在起飞瞬间给大控制量。

3.3 学习率和切换增益的配合关系

这两个参数是耦合的。学习率大、切换增益小,网络估计快但初期可能震荡;学习率小、切换增益大,稳但抖振压不下去。我一般先让切换增益保持纯滑模的 60%,然后逐步加学习率,看角速度曲线的高频分量什么时候开始变大,退回到前一档。

仿真里可以用tic/toc记录每步耗时,神经网络前向加反向更新在 MATLAB 里单步大概 20 到 50 微秒,跑 10 秒仿真用ode45变步长大概几秒到十几秒,取决于机器。如果你要上机载,得转 C 代码,MATLAB Coder 能直接生成,但quatmultiply这类函数要替换成手写实现。

4. 在 MATLAB/Simulink 里搭一套可跑的仿真:从脚本到曲线

4.1 纯脚本仿真框架与主循环

先不急着上 Simulink,用纯脚本跑通最小闭环,确认控制律和自适应律没问题,再往 Simulink 搬。主循环结构如下:

clear; clc; % 参数 params.J = diag([0.02, 0.02, 0.04]); params.Lambda = diag([2, 2, 1.5]); params.eta = diag([0.5, 0.5, 0.3]); params.phi_b = 0.05; params.Gamma = diag([50, 50, 30]); params.dt = 0.001; params.V = 0.1 * randn(9, 6); % 初始状态 q0 = [1; 0; 0; 0; 0; 0; 0]; W = zeros(3, 9); % 期望姿态 q_d = [1; 0; 0; 0]; % 仿真 T = 10; N = T / params.dt; q = q0; log = zeros(N, 14); for k = 1:N t = k * params.dt; % 扰动:阵风模拟 d = [0.02*sin(2*pi*0.5*t); 0.015*sin(2*pi*0.8*t); 0.01*sin(2*pi*0.3*t)]; % 控制 [tau, W] = nn_adaptive_smc(q, q_d, W, params); % 积分一步(欧拉) dq = quad_attitude_dyn(t, q, params.J, tau, d); q = q + params.dt * dq; q(1:4) = q(1:4) / norm(q(1:4)); % 四元数归一化 log(k, :) = [t, q', tau', d']; end % 画图 figure; subplot(3,1,1); plot(log(:,1), log(:,2:5)); legend('q_w','q_x','q_y','q_z'); title('四元数响应'); subplot(3,1,2); plot(log(:,1), log(:,6:8)); legend('w_x','w_y','w_z'); title('角速度'); subplot(3,1,3); plot(log(:,1), log(:,9:11)); legend('tau_x','tau_y','tau_z'); title('控制力矩');

逻辑说明:主循环用固定步长欧拉积分,虽然精度不如ode45,但和实际飞控的离散控制周期一致,方便后面转 C。四元数每步归一化,防止数值漂移。扰动用三个不同频率正弦叠加,模拟阵风的多频特性。

参数说明:dt = 0.001对应 1 kHz 控制频率,实际飞控常见 400 Hz 到 1 kHz。phi_b = 0.05是饱和函数边界层,太小抖振抑制不够,太大跟踪精度下降。Gamma和eta的配合按上一章的方法调。

4.2 把脚本搬进 Simulink 的模块划分

Simulink 里建议分四个子系统:动力学模块(用 MATLAB Function 块封装quad_attitude_dyn)、控制器模块(封装nn_adaptive_smc)、扰动源模块(用 Signal Builder 或 From Workspace)、可视化模块。控制器模块里神经网络权值用persistent变量或 Unit Delay 反馈实现,不要用全局变量。

一个容易翻车的地方:Simulink 的 MATLAB Function 块不支持quatmultiply这类工具箱函数,得手写四元数乘法和求逆。手写版本:

function q_out = quat_multiply(a, b) q_out = [a(1)*b(1) - a(2)*b(2) - a(3)*b(3) - a(4)*b(4); a(1)*b(2) + a(2)*b(1) + a(3)*b(4) - a(4)*b(3); a(1)*b(3) - a(2)*b(4) + a(3)*b(1) + a(4)*b(2); a(1)*b(4) + a(2)*b(3) - a(3)*b(2) + a(4)*b(1)]; end

参数说明:输入 a 和 b 都是 4x1 列向量,顺序是 [w; x; y; z]。这个函数在脚本和 Simulink 里都能用,替换掉工具箱依赖。

4.3 仿真结果怎么看:三个关键曲线

跑完仿真,重点看三条曲线。第一,四元数误差是否在 2 秒内收敛到 0.01 以内,收敛太慢说明 Λ 太小或学习率不够。第二,角速度曲线的高频毛刺幅度,和纯滑模对比,神经网络自适应滑模的角速度高频分量应该明显小。第三,控制力矩是否饱和,如果力矩一直在限幅值附近,说明切换增益或学习率给大了。

我一般会把纯滑模和神经网络自适应滑模跑同一组扰动,叠在一起画。如果神经网络版本的角速度毛刺反而更大,先查权值更新步长是不是和仿真步长不一致,再查学习率是不是超过稳定边界。

5. 避坑与排查:神经网络自适应滑模最容易翻车的五个地方

5.1 权值发散导致控制力矩爆掉

现象:仿真跑几秒后控制力矩突然冲到很大,角速度发散。原因:学习率 Γ 太大,或者权值更新没有做投影映射(projection),权值无界增长。解决:给权值加一个范数上界,超过就投影回球内;学习率从 10 起步,逐步加。

5.2 四元数符号跳变引起姿态误差计算错误

现象:姿态误差四元数突然从接近 [1;0;0;0] 跳到 [-1;0;0;0],误差矢量部分符号翻转,控制量反向。原因:四元数双覆盖,q 和 -q 表示同一姿态。解决:计算误差四元数后,如果标量部分小于零,整体取负。

if q_err(1) < 0 q_err = -q_err; end

5.3 饱和函数边界层太窄等于没加

现象:角速度曲线还是有明显抖振,和纯滑模差不多。原因:phi_b设成 0.001 这种极小值,饱和函数退化成符号函数。解决:phi_b取 0.01 到 0.1 之间,根据角速度噪声水平调,噪声大就取大。

5.4 神经网络输入没有归一化

现象:网络输出估计值一直饱和在 ±1 附近,扰动补偿效果差。原因:姿态误差和角速度误差量级差很多,直接拼成输入向量,网络权值更新被大量级信号主导。解决:输入分别除以各自的典型幅值,姿态误差除以 0.1,角速度误差除以 1.0。

5.5 仿真步长和权值更新步长不一致

现象:仿真结果和理论分析对不上,权值更新像是随机游走。原因:ode45变步长,但权值更新用了固定dt,两者不同步。解决:要么全用固定步长,要么把权值更新也写成微分方程让求解器一起积分。我一般全用固定步长,省事。

6. 进阶验证:把自适应滑模和 DQN、PPO 放一起比,以及上机前的检查清单

仿真跑通之后,下一步是验证这套方案到底比纯滑模强多少,以及能不能上机。我一般做三组对比:纯滑模、神经网络自适应滑模、以及用强化学习(DQN 或 PPO)调参的滑模。强化学习那组不是用来替代滑模的,是用来找 Λ 和 η 的最优组合,减少手动调参时间。MATLAB 的 Reinforcement Learning Toolbox 能直接搭 PPO,但训练一个姿态控制策略动辄几小时,实际项目里我更多用它对已有控制器做参数微调,而不是从零学控制律。

上机前检查清单,按顺序过一遍:

检查项通过标准常见问题
四元数归一化每步范数误差 < 1e-6忘记归一化,姿态漂移
权值有界范数 < 设定上界无投影,权值发散
控制力矩限幅不超过电机物理上限仿真不限幅,上机饱和
学习率与步长匹配离散更新稳定步长变了没改学习率
扰动估计延迟相位滞后 < 10 ms网络太大,推理慢

最后说一个我自己的习惯:每次改完控制律,先跑 10 秒悬停,再跑 10 秒阶跃响应,最后跑 30 秒阵风扰动。三组都过了才往 Simulink 搬,Simulink 过了才生成 C 代码。生成 C 之后,第一件事是在硬件在环(HIL)里跑一遍,确认浮点精度和实时性。神经网络那部分如果单步超过 100 微秒,就得考虑减隐层节点或者用定点化。

这套方案值不值得做?如果你手上已经有飞控平台,只是想把抗扰能力提一档,神经网络自适应滑模的改动量主要在控制律那一层,传感器和执行器不用动,投入产出比是划算的。但如果你还在选型阶段,先确认你的飞控 MCU 有没有足够的浮点算力,没有的话,纯滑模加扰动观测器可能更实际。

希望帮到你。

本文还有配套的精品资源,点击获取

返回列表