资讯动态

四旋翼姿态控制ADRC仿真:建模、调参与避坑全流程

发布时间:2026/10/27 1:04:13 来源:尧图企业网站定制
简介面向无人机控制方向的学习者与Matlab仿真使用者这份资源提供了一套可直接运行的四旋翼自抗扰姿态控制器仿真方案。内容完整覆盖四旋翼姿态模型、力矩方程与角运动方程并针对滚转、俯仰、偏航三个姿态角分别设计了自抗扰控制器参数已预先整定可免去繁琐调试。控制器基于扩张状态观测器实时估计内外扰动在存在风扰或模型不确定时仍能维持稳定的姿态控制效果同时整套代码结构简洁、注释清晰读者可在此基础上自行替换为PID、LQR等其他控制律进行对比分析。压缩包内共11个文件以txt技术说明文档为主辅以jpg示意图、html分析页面和doc文档分别对应模型推导、参数整定、仿真结果分析与参考文献整理整体大小仅313KB。目前已有73人学习下载适合正在研究自抗扰控制、四旋翼建模或姿态控制算法的读者快速上手也可作为课程设计或毕业设计的重要参考。1. 为什么四旋翼姿态控制里大家都在换 ADRC先讲清楚这套仿真在解决什么这个仿真工程对应的是四旋翼无人机姿态控制里最典型的那块硬骨头把滚转、俯仰、偏航三个姿态角的动力学用 Matlab 搭起来再用 ADRC自抗扰控制做闭环控制模型、力矩方程、角运动方程、三个姿态角的反馈全部包含在内而且在给定参数下能直接跑出收敛结果。所谓“已调好”指的是控制器已经完成仿真层面的参数整定不需要你再去盲猜一套初始值。它解决的是最磨人的一个痛点姿态动力学非线性、通道间耦合、扰动不确定常规 PID 在仿真里调起来很脆换一组惯量参数就振荡而 ADRC 可以用扩张状态观测器把“模型误差外部扰动”当成总扰动实时估出来并补偿掉。这套思路适合刚接触四旋翼建模的同学验证数学模型也适合已经在飞控上写过控制算法的工程师快速搭一个可复现的对比基线用来评估 ADRC 到底比 PID 强在哪。2. 姿态模型的数学基底坐标系、力矩方程与角运动方程怎么落到 Matlab 代码2.1 先定坐标系和欧拉角顺序模型差之毫厘控制失之千里四旋翼的姿态模型首先取决于坐标系定义和欧拉角旋转顺序。常见做法是地面坐标系选 NED北东地机体坐标系固定在机身上滚转角 phi、俯仰角 theta、偏航角 psi 按 Z-Y-X偏航-俯仰-滚转的顺序给出。仿真里把地面系当作惯性系使用飞行高度变化不大时忽略重力加速度随高度的变化这样模型足够简单又能把姿态控制的核心问题呈现出来。做姿态控制仿真时通常把重心位置设定在机架中心不去管位置环只关注姿态角对指令的跟踪。描述姿态角对时间的导数时需要用到欧拉角运动学关系psi_dot (q * sin(phi) r * cos(phi)) / cos(theta) theta_dot q * cos(phi) - r * sin(phi) phi_dot p q * sin(phi) * tan(theta) r * cos(phi) * tan(theta)这里 p、q、r 是机体角速度在机体轴上的分量。大多数四旋翼教材直接把这组公式当作姿态运动学核心而真实飞控里角度变化率并不会完全等于角速度分量正是因为存在欧拉角顺序和坐标投影的问题。模型里如果忽略陀螺力矩和旋翼的转动惯量姿态动力学就会简化仿真跑起来更稳定但精度会下降。这类带简化假设的模型在 ADRC 场景下其实更合适因为控制器本身会把模型误差当作总扰动来补偿简化模型反而能突出 ADRC 的价值——你不需要把模型建得极其精确扩张观测器会把差异“吃掉”。不同教材对欧拉角正方向的定义存在差异有的用右手定则有的用航空惯例如果你从某个开源工程里拷了一段模型代码但坐标系定义没跟着一起拷过来仿真结果就会完全反掉。我见过有人把滚转力矩正方向写反导致控制器输出正反馈仿真直接发散最后排查了两天才发现是符号问题。所以第一步务必先确认欧拉角旋转顺序和电机编号再开始写代码。2.2 力矩方程把电机拉力和阻力矩写成可仿真的形式常见的四旋翼力矩方程会写成三个通道。绕滚转轴的力矩 L 主要来自左右电机的拉力差绕俯仰轴的力矩 M 来自前后电机的拉力差绕偏航轴的力矩 N 来自四个旋翼反扭矩的差。若采用简化模型可以把三个力矩写成如下形式L l * k * (omega2^2 - omega4^2) M l * k * (omega3^2 - omega1^2) N b * (omega1^2 - omega2^2 omega3^2 - omega4^2)这里 l 是机臂长度k 是拉力系数b 是反扭矩系数omega_i 是四个旋翼的转速。把模型搬到 Matlab 里时我不建议在 Simulink 里用一堆 gain 模块硬拼这些公式而是先写成函数文件把输入转速、模型参数转成力矩和力输出。这样后续换机型只要改参数表不用重构整个仿真。下面给出一个可直接使用的函数骨架它同时返回合力和三轴力矩function [F, M] quadrotor_wrench(omega, param) % 输入 omega: [w1 w2 w3 w4] 四个旋翼转速单位 rad/s % 输出 F: 机体 z 轴方向的总拉力 % M: [Mx My Mz] 滚转/俯仰/偏航力矩 w1 omega(1); w2 omega(2); w3 omega(3); w4 omega(4); F param.k * (w1^2 w2^2 w3^2 w4^2); Mx param.l * param.k * (w2^2 - w4^2); % 右侧电机拉力大 - 左滚 My param.l * param.k * (w3^2 - w1^2); % 前侧电机拉力大 - 后仰 Mz param.b * (w1^2 - w2^2 w3^2 - w4^2); % 反扭矩差 - 偏航 end这段代码里值得注意的两个地方一个是 F 的定义在机体坐标系下默认拉力沿机体 z 轴向上如果你需要把 F 投影到地面系还要用姿态旋转矩阵左乘另一个是 Mz 的正负号取决于电机旋转方向定义不同教材和实际机架差别很大建议先用自己的电机布局验证符号。参数结构体 param 可以统一在脚本里命名例如 param.k 1.5e-6单位 kg·mparam.l 0.16单位 mparam.b 2e-7单位 kg·m^2。这些值在仿真里不需要特别精确因为 ADRC 会把未建模误差当作扰动处理。如果想把模型做得更真实可以在力矩方程中继续加入转子惯性和陀螺效应例如把滚转角加速度写成包含陀螺力矩的形式。这类扩展模型会增加仿真计算量但能检验 ADRC 观测器的抗扰动能力。做 ADRC 实验时建议每次只加一种被忽略项观察观测器能否把它估计出来并补偿掉而不是一次性把模型复杂度全开否则很难定位问题来自模型还是控制器。2.3 角运动方程把姿态角和角速度状态搭成 ODE有了力矩之后要得到角加速度还得把角运动方程写成状态空间形式。最常用的做法是把状态变量选为三个欧拉角和三个机体角速度写成六维姿态状态向量。一个典型的简化姿态动力学状态方程如下忽略陀螺力矩时phi_ddot (Jyy - Jzz)/Jxx * theta_dot * psi_dot Mx/Jxx theta_ddot (Jzz - Jxx)/Jyy * phi_dot * psi_dot My/Jyy psi_ddot (Jxx - Jyy)/Jzz * phi_dot * theta_dot Mz/Jzz这组式子看起来简单但直接搭 Simulink 积分器会让模型很乱最后还得画一张庞大的接线图很难维护。更推荐的做法是把姿态动力学写成一个独立的 ode 函数配合 ode45 或 Simulink 的 MATLAB Function 模块调用。下面是一个可以直接配合 ode45 使用的姿态状态导数函数function dstate att_state_deriv(t, state, M, param) % 姿态角运动方程的状态导数用于 ode45 或 Simulink 内嵌函数 % state [phi, theta, psi, p, q, r] phi state(1); theta state(2); psi state(3); p state(4); q state(5); r state(6); % 角运动学欧拉角变化率与机体角速度的关系 dphi p q*sin(phi)*tan(theta) r*cos(phi)*tan(theta); dtheta q*cos(phi) - r*sin(phi); dpsi (q*sin(phi) r*cos(phi)) / cos(theta); % 角动力学力矩除以转动惯量并保留科氏耦合项 dp (param.Jyy - param.Jzz)/param.Jxx * q * r M(1)/param.Jxx; dq (param.Jzz - param.Jxx)/param.Jyy * p * r M(2)/param.Jyy; dr (param.Jxx - param.Jyy)/param.Jzz * p * q M(3)/param.Jzz; dstate [dphi; dtheta; dpsi; dp; dq; dr]; end写这段时注意几个容易踩坑的点。第一个是 theta 接近 ±90° 时 tan(theta) 和 1/cos(theta) 会发散所以如果仿真场景包含大机动强烈建议改用四元数状态欧拉角只做输出显示。第二个是科氏耦合项在这个模型里量级比较小但不要一开始就删掉因为 ADRC 的观测器会把耦合当作扰动我们要验证的是它到底能不能对付得了耦合若直接把耦合删掉再测试就失去了意义。第三个是惯量参数不要随便填仿真中常见 Jxx Jyy ≈ 0.01、Jzz ≈ 0.02 的量级具体数值根据你参考的机架设定否则角速度动态会明显失真。把模型搭好之后姿态仿真就有了可复现的数学底座剩下的工作就是挂上 ADRC 控制器并调节参数。实践中很多“仿真发散”案例并不是控制器参数错了而是模型符号或欧拉角顺序出了问题所以先把开环模型用零输入跑一遍确认状态不会漂到奇异点再接入闭环。3. ADRC 姿态控制器的设计三个通道为什么要各配一个扩张状态观测器3.1 从 PID 到 ADRC 的换道理由模型误差不再是心头大患ADRC 在四旋翼姿态控制里被很多人接受核心在于它把“模型误差 外部扰动 通道耦合”统一建模成总扰动并用扩张状态观测器实时估计再通过控制量补偿。做四旋翼姿态仿真的人都清楚PID 调好一组参数后只要把模型里的惯量参数换一下或者给通道加一个脉冲扰动姿态响应就可能出现震荡甚至发散。这背后的原因是 PID 没有显式处理模型不确定性而是靠积分项慢慢消化在强耦合和快速变化的扰动下很容易超调。ADRC 的姿态内环一般拆成三个独立通道滚转、俯仰、偏航每个通道一个 ADRC 控制器。每个 ADRC 内部包含三块——跟踪微分器TD用来给参考输入安排过渡过程扩张状态观测器ESO用来估计姿态角和总扰动以及状态误差反馈控制律用来生成力矩指令。三通道之所以能独立设计是因为把通道间的耦合放进了总扰动里由 ESO 去估计和补偿这正是 ADRC 用在四旋翼姿态环里最舒服的地方。你不需要精确建模耦合项只需要保证每个通道的 b0 量级准确剩下的交给观测器。3.2 离散 ESO 怎么写成代码先看公式再看实现ADRC 的观测器是整个控制器的黑匣子也是调参时最需要盯住的核心。在仿真里直接用连续积分器也能跑但要和实际飞控的行为对齐一般建议用离散形式毕竟飞控里跑的都是离散算法。以角速度环的一阶对象为例常见离散 ESO 公式如下e z1 - y z1 z1 h * (z2 - beta1 * e) z2 z2 h * (z3 b0 * u - beta2 * e) z3 z3 h * (-beta3 * e)其中 z1 是角速度估计z2 是角加速度估计z3 是总扰动估计b0 是控制增益的粗估。在四旋翼姿态仿真里如果直接对角度环做二阶对象的 ESO公式会变成三个状态估计角度、角速度和总扰动但思路一致把未知部分归入扰动项再用第三维状态把它估计出来。仿真包里常见的实现是把这组迭代写成 MATLAB Function 子函数每一帧调用一次而不是用 Simulink 积分器去搭观测器。下面给出一个用于角度环的离散 ESO 实现这也是姿态 ADRC 里最常见的代码片段。注意 h 是采样周期u 是控制力矩指令function [z1, z2, z3] eso_step(z1, z2, z3, y, u, h, param) % 离散扩张状态观测器 % y: 实际姿态角或角速度反馈 % u: 归一化或实际控制量 % z1: 状态估计角度或角速度 % z2: 状态微分估计 % z3: 总扰动估计 e z1 - y; z1 z1 h * (z2 - param.beta1 * e); z2 z2 h * (z3 param.b0 * u - param.beta2 * e); z3 z3 h * (-param.beta3 * e); end解释一下 b0 的含义b0 是控制输入到状态加速度的增益近似值通常取力矩系数除以惯量实际上由于模型误差和通道耦合的存在b0 并不准确但 ADRC 的好处就在于不需要它精确量级对就行。beta1、beta2、beta3 三个观测器增益也不用靠试常见做法是先用带宽法设观测器带宽 wo取 beta1 3wobeta2 3wo^2beta3 wo^3然后再微调。在四旋翼姿态仿真里 wo 从 20 起步往 50100 调。注意 wo 太大会把噪声和模型离散误差放大太小会补偿滞后这个权衡是仿真阶段最值得摸索的内容。3.3 跟踪微分器和误差反馈让阶跃指令不再“吓到”控制器TD 的作用是让参考输入没有突变避免初始时刻控制力矩超限。你直接给 30° 阶跃会让角速度需求瞬间拉满而经过 TD 之后参考信号变成平滑曲线姿态响应看起来更有工程意义。跟踪微分器常见的离散写法如下输入 v 是期望姿态角v1 是跟踪信号v2 是跟踪信号的微分r 决定过渡速度function [v1, v2] td_step(v1, v2, v, h, r) % 跟踪微分器安排过渡过程r 越大跟踪越快 v1 v1 h * v2; v2 v2 h * (-r * sign(v1 - v v2 * abs(v2) / (2 * r))); end这可能是 ADRC 里最容易产生“玄学感”的地方——若 r 选太小姿态响应会慢得让你怀疑控制器没起作用若 r 选太大TD 的效果又等于没加。仿真里一般用 r 80150 搭配 30° 阶跃让过渡时间压在 0.20.4 秒之间。需要注意的是上面给出的是简化的离散形式如果对跟踪精度要求高建议换成韩京清提出的 fhan 最速控制综合函数那个包含更多代数运算和符号判断跟踪效果更接近理论。误差反馈环节可以选择线性或非线性两种组合。常见做法是取 e1 v1 - z1e2 v2 - z2控制量 u0 kp * e1 kd * e2这是线性组合也可以使用非线性 fal 函数组合来增加收敛速度。姿态仿真里线性组合已经很容易跑出漂亮的响应非线性组合只在强扰动场景下能看出来优势。角度环和角速度环串级时还要把总扰动补偿项加回来u (u0 - z3) / b0这一行是 ADRC 实现里最关键的动作漏掉它整个算法就退化成带滤波的高级 PD抗扰能力大打折扣。3.4 串级结构怎么定角度环外环 角速度环内环把 ADRC 放在姿态环里常见做法是外环角度环用较保守的 P TD内环角速度环用完整的 ESO 加补偿也就是内外环不完全对称。原因很直接角度环的模型是运动学关系误差积累慢角速度环才真正和力矩方程打交道扰动也主要集中在这里。所以仿真包里如果是串级结构多数是角度环用 TD P角速度环用 ADRC。四旋翼力矩指令从角速度环输出再通过混控矩阵换成四个旋翼转速指令接到模型上。这里还要注意一个实际情况偏航通道的力矩来源是反扭矩差系数 b 比拉力系数 k 小一两个数量级三个通道输出力矩的量级差异很大所以一个通道调好的 b0 对另一个通道完全无效。偏航通道经常出现“转不动”或者“慢半拍”的现象多半就是 b0 的量级没跟力矩系数对齐。三个通道的 ESO 参数最好分开整定不要共享同一套带宽。这些细节决定了 ADRC 仿真工程在换机型时到底能不能复现也是从“能跑”走向“可控”的关键一步。4. Simulink 仿真工程的搭建与参数落地一套可以直接复现的最小闭环4.1 模型结构的总览从指令输入到姿态输出一共几层在 Simulink 里搭建 ADRC 姿态控制器仿真时推荐的信号流如下期望姿态角 - 角度环 TD 与误差计算 - 角速度环 ADRC - 混控与力矩方程 - 姿态动力学模型 - 姿态角和角速度反馈。其中姿态动力学模型既可以写在 S-Function 里也可以用 MATLAB Function 调用前面写的 att_state_deriv 函数。如果你手头没有 Simulink 的完整授权也可以把整个仿真放在 MATLAB 脚本里跑用 for 循环逐时刻更新状态这样反而更容易调试只是可视化弱一些。我一般先写脚本用 ode45 验证整个闭环算法再去 Simulink 里搭模块化工程。这样遇到仿真发散时能快速判断是离散化步长问题还是控制器逻辑问题。若从一开始就堆积 Simulink 模块出现发散时很难定位是哪个环节出了问题。4.2 最小闭环脚本滚转通道先跑通再扩到三个通道下面是能直接复现的滚转通道最小闭环脚本。为了篇幅角速度环只保留一个通道实际三通道扩展就是把这个 ADRC 复制三段并把通道对应的状态和力矩对上。% 滚转通道 ADRC 闭环验证脚本 % 状态向量x [phi, p]即滚转角和滚转角速度 clear; clc; param.k 1.5e-6; param.l 0.16; param.b 2e-7; param.Jxx 0.01; param.Jyy 0.01; param.Jzz 0.02; h 0.001; % 仿真步长 1 ms T 5; n T / h; % 5 秒仿真 % ADRC 参数带宽法初值 wo 60; wc 30; b0 param.l * param.k / param.Jxx; % 滚转通道力矩/惯量 beta1 3 * wo; beta2 3 * wo^2; beta3 wo^3; kp wc^2; kd 2 * wc; % 状态初值 phi 0; p 0; z1 0; z2 0; z3 0; v1 0; v2 0; phi_cmd deg2rad(30); % 30 度滚转阶跃 % 记录时间历程 t_log zeros(n, 1); phi_log zeros(n, 1); u_log zeros(n, 1); for k 1:n t k * h; % 跟踪微分器 [v1, v2] td_step(v1, v2, phi_cmd, h, 120); % 角度环误差 e1 v1 - z1; e2 v2 - z2; u0 kp * e1 kd * e2; u (u0 - z3) / b0; % 总扰动补偿 % 力矩方程 Mx u; My 0; Mz 0; % 模型更新半隐式欧拉避免代数环 dp (param.Jyy - param.Jzz) / param.Jxx * 0 * 0 Mx / param.Jxx; p_new p h * dp; phi_new phi h * (p 0); % 小角度下 dphi 约等于 p % 观测器更新 eso_param struct(beta1, beta1, beta2, beta2, beta3, beta3, b0, b0); [z1, z2, z3] eso_step(z1, z2, z3, p_new, u, h, eso_param); phi phi_new; p p_new; t_log(k) t; phi_log(k) rad2deg(phi); u_log(k) u; end % 绘图查看响应 plot(t_log, phi_log, LineWidth, 1.5); grid on; xlabel(时间 (s)); ylabel(滚转角 (deg)); title(滚转通道 ADRC 阶跃响应);解释几个要点。半隐式欧拉里先把角速度更新了再用来更新角度这样能避免单步内的代数依赖比显式欧拉稳定得多。观测器里反馈的是真实角速度 p_new仿真里角度和角速度都可以用一般角速度反馈更直接。b0 在脚本里取理想值力矩除以惯量若故意填一个更小的值比如打个 0.7 折系统依然能稳定只是响应会慢一点这正是 ADRC“不过度依赖精确模型”的体现。把 phi_cmd、wo、kp 这类参数直接写在脚本头部方便反复调整对比不要把它们散落在循环内部。单通道跑通之后三通道扩展的要点在于把三个通道的控制器实例分开每个实例保存自己的 z1、z2、z3 和 v1、v2。比较稳妥的做法是把每个通道写成结构体数组例如 ctrl(1).z1、ctrl(2).z1这样在循环里做索引更新代码比复制粘贴三份要清晰得多。如果你倾向 Simulink就把每个通道做成子系统三个子系统并列输入期望角输出力矩模型统一接混控矩阵。4.3 三通道扩展时的混控矩阵从力矩到四个电机转速仿真工程中从力矩指令到旋翼转速的那一步最容易出错。三通道 ADRC 输出 Mx、My、Mz加上需要维持的总拉力 F通过混控矩阵反解出四个电机的转速平方。常见混控矩阵可以写成如下代码function [w1, w2, w3, w4] mixer(F, Mx, My, Mz, param) % 逆混控总拉力 三轴力矩 - 四个旋翼转速平方 % 系数矩阵符号取决于机架电机布局务必核对 A [param.k, param.k, param.k, param.k; -param.l * param.k, 0, param.l * param.k, 0; 0, -param.l * param.k, 0, param.l * param.k; param.b, -param.b, param.b, -param.b]; T2 A \ [F; Mx; My; Mz]; w1 sqrt(max(T2(1), 0)); w2 sqrt(max(T2(2), 0)); w3 sqrt(max(T2(3), 0)); w4 sqrt(max(T2(4), 0)); end这里 A 矩阵的符号组合一定要对着自己的机架旋转方向和电机布局看。不同教材里滚转和俯仰行的正负号经常是反的如果姿态响应方向反了多半是这个矩阵的符号错了而不是控制器调错了。另外用反斜杠解线性方程比手写逆矩阵更好扩展未来若改成六旋翼布局也只需要改 A 矩阵的维度。4.4 别忘了参考输入限幅和积分保护姿态环仿真里常见的问题是给大阶跃指令时ADRC 输出力矩超出物理上限。真实无人机力矩是有饱和的仿真里如果不加限幅控制器会输出远超实际的力矩指令姿态响应在仿真里看着完美但根本无法在真实硬件上实现。所以仿真工程都会在控制器输出后加饱和模块把 Mx、My、Mz 限制在电机能力对应的范围内。加限幅之后你还会发现一个现象太激进的参数会让控制量撞在限幅上姿态响应整体变慢稳定性反而变差。我一般先不加饱和整定出一组响应等指标满足后再加饱和重新观察若加了饱和就振荡说明观测器带宽和控制器带宽都偏高需要压下来。这个经验在实物调试时同样适用仿真里的限幅参数要和电机的最大拉力对应才能保证仿真结果对实物有参考价值。4.5 从脚本搬到 Simulink哪些模块要少用哪些可以放心用如果你决定在 Simulink 里复现整套模型有几个地方要提前注意。首先是避免用 Memory 模块手动做单位延迟ADRC 的状态更新在 Simulink 里建议用 Unit Delay 或者 MATLAB Function 模块的持久变量这样时序更清晰。其次是不要把整个模型都塞进一个 MATLAB Function 模块再在里面操作全局变量全局变量极易造成多实例间的同步问题建议把模型、控制器、观测器拆成独立函数信号线显式连接。S-Function 写姿态动力学时建议选择 Level-2 MATLAB S-Function接口比 Level-1 更稳定支持向量输入输出。如果只做仿真验证普通 MATLAB Function 配合固定步长完全够用。仿真步长固定在 0.001 秒解算器选 ode4这是四旋翼模型仿真里最稳的组合。不要用变步长因为离散控制器和连续模型混在一起变步长在状态突变时容易触发额外误差导致发散这也是“仿真发散”最容易被忽略的根源之一。5. 仿真避坑清单发散、震荡、静差三种最常见的翻车现场5.1 现象仿真一开始就发散状态直接飞掉现象是接入闭环后前 0.1 秒内角度和角速度直接爆炸甚至出现 Inf 或 NaN。八成原因是模型状态更新顺序错了或者 ESO 的观测值在第一步还没建立起来就参与反馈控制器输出算出了一个巨大力矩。另一个高频原因是 b0 的正负号反了补偿方向变成正反馈不炸才怪。解决方式分几步先把控制量 u 强制为 0跑一遍开环模型确认模型本身不产生 NaN然后给角速度环一个很小的初始误差把 ESO 增益调低观察 z1、z2 是否跟得上真实状态最后把补偿项关掉只保留 PD 部分确认基本闭环稳定后再把 -z3/b0 加回来。这相当于把 ADRC 逐级拆开做验证比直接全套猛跑要快得多。仿真发散时先审模型状态更新顺序和符号问题最后才轮到控制器参数。5.2 现象稳态有小静差但增加 kp 后开始震荡期望指令为阶跃时稳态误差不为零把角度环 kp 往上加系统反而震荡甚至发散这是 ADRC 调参过程中的典型困境。原因通常是角度环和角速度环的带宽拉不开串级系统里内外环带宽比值不够。常见做法是内环比外环快 35 倍比如外环带宽 510 rad/s内环角速度环控制在 3080 rad/s观测器带宽 wo 再高于内环控制器带宽 23 倍。如果 wo 设 60、wc 设 50两者太接近中频段相互作用就会引发震荡。另一个隐藏原因是 ESO 的 z3 在稳态时没有完全收敛到真实总扰动残差一直存在被 PD 慢慢磨就表现为静差。遇到这种情况不要只调 kp先把观测器带宽 wo 加到原来的 1.5 倍观察 z3 的收敛曲线是不是更贴近常数。wo 一高就振说明离散步长太大或反馈信号里有高频抖动把 h 从 0.01 改到 0.001 往往立刻改善。5.3 现象控制量一直顶在限幅上姿态响应却像蜗牛这说明你看到的控制指令根本不在有效工作区ADRC 输出一直饱和补偿能力被限幅劫持。原因大概率是观测器里 b0 估计过小使补偿量被放大后顶在限幅上也可能是因为期望阶跃太大TD 的过渡时间设得太短把能量都压在初始段。解决方式是先检查限幅是否匹配当前机动需求再逐步增大 TD 的 r 值拉开过渡时间同时记录三个通道控制量的时间历程。偏航通道最容易出现这种问题因为偏航力矩系数远小于拉力系数同一个控制框架下需要单独设 b0。把三个通道的 b0 分别标注来源并在日志里输出 Mx、My、Mz 峰值若某个通道持续贴着限耗超 30% 时间就回调整定参数。这条经验能解决“偏航通道转不动”的迷惑很多时候是混控矩阵里偏航系数数量级标错了。5.4 现象同一套参数换个机型的模型就发散“调好”一组 ADRC 参数后把 Jxx、Jyy、Jzz 换成另一架飞机的数值系统立刻发散。原因在于 ADRC 虽然不要求精确模型但 b0 和观测器带宽仍然依赖惯量量级换了模型但没同步换 b0控制器补偿的物理意义就错位了。解决方式是让 b0 从模型参数里实时算出来换模型时只改参数结构体不要写死数值。如果换机型后还出现明显振荡要注意惯量比 Jyy/Jxx、Jzz/Jxx 差别过大时姿态耦合是否超出了 ESO 的估计能力范围。这时可以检查科氏耦合项在模型里是否被正确保留。ADRC 不是魔弹它把模型不确定性放进扰动观测器前提是 b0 的方向和量级没有错否则观测器补不回来。5.5 现象角度反馈用度控制量用弧度曲线全是毛刺模型里状态和指令混用 deg 和 rad观测器观测到的信号会出现尺度跳变z1 和 z2 永远配不上曲线出现毛刺或阶梯状。解决方式只有一个统一在接口处转换。建议在脚本最开头定义 deg2rad 和 rad2deg 的使用规范Simulink 里用增益模块标注 1/57.3 或使用单位转换模块不要靠“心里记得”在积分器前后混用。排查这类问题很简单画出 z1 和实际状态 phi 的对比图如果形状一致但幅度差了约 57 倍那问题一目了然。单位问题解决之后很多“响应慢半拍”“稳态漂移”的怪现象都会自动消失。这也是仿真包里被“调好”之后最容易被忽视的地方因为曲线不光滑时你不会立刻联想到单位。6. 验证鲁棒性和进阶技巧给仿真加点扰动才算真正把 ADRC 用起来验证 ADRC 姿态控制器的水平不能只看阶跃响应多漂亮要看加扰动之后的恢复能力。常见做法是在模型输入侧加一个脉冲力矩例如在 2 秒时给滚转通道加幅值 0.5 N·m、持续 0.2 秒的扰动力矩模拟一阵阵风的影响。把同样的扰动加到 PID 控制器上做对比你会发现 ADRC 的恢复时间和对扰动的最大偏差通常会优于 PID这才是你选择 ADRC 的证据也是仿真阶段最有价值的一份实验数据。从脚本进阶到工程验证时我建议做三件事。第一件是记录每个通道的扰动观测值 z3画在图上看它能不能在扰动发生后快速跟踪到真实值附近如果 z3 的响应比姿态角偏差还慢说明观测器带宽压不住了这也是你写报告时最直接的论据。第二件是跑一组参数扫描把 wo 从 30 到 120 各跑一次记录超调量和调节时间做成表格这样你能知道这个仿真工程在实际调参时的安全区间在哪里。第三件是换一组惯量参数再跑一次闭环如果稳定性和响应仍然可用说明这套 ADRC 不是只在特定参数下工作的“书上例子”。如果真想深入建议读三篇经典文献韩京清先生的《自抗扰控制技术》相关论文高志强教授关于带宽调参的英文文章以及四旋翼建模里比较标准的综述类文献。标题里说附带参考文献仿真包里常见的参考文献也正是这几个方向一边看一边对照 z3 的扰动估计曲线会比空调参数理解得快得多。最后分享一个我自己的习惯每次调完参数都整组数据存成带时间戳的 mat 文件记录当时用的指令、观测器带宽、限幅值再把姿态响应截图保存。因为 ADRC 调参的“好”和“坏”差距往往就在几个数值之间事后翻看日志能减少大量重复劳动。希望这个方向的经验能帮到你在四旋翼姿态控制这条路上少踩坑多一份从仿真走向实物的信心。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑