1. 项目概述:当四旋翼遇上自抗扰控制
去年调试无人机时,我遇到过这样一个场景:在户外飞行测试中,突发的阵风让无人机像醉汉一样摇晃不止。传统PID控制器需要反复调整参数才能勉强稳住姿态,而改用自抗扰控制器(ADRC)后,系统竟能自动抵消风扰,保持稳定悬停。这个案例让我深刻体会到ADRC在无人机控制中的独特价值。
四旋翼无人机作为典型的欠驱动系统,其姿态控制面临三大核心挑战:
- 强耦合性:俯仰、横滚和偏航运动相互影响
- 非线性特性:空气动力学效应随姿态角变化呈现复杂非线性
- 扰动不确定性:风扰、负载变化等外部干扰难以建模
自抗扰算法通过独特的"总扰动"概念,将模型不确定性和外部干扰统一视为系统扰动进行实时估计和补偿。其核心优势在于:
- 不依赖精确数学模型
- 对参数变化鲁棒性强
- 动态响应速度快
2. 自抗扰控制原理深度解析
2.1 ADRC的三重防护体系
自抗扰控制器就像给无人机配备了一个智能抗干扰系统,由三个关键部件构成:
-
跟踪微分器(TD)
解决设定值突变引起的超调问题。通过安排过渡过程,使参考信号及其微分信号平滑过渡。在实际调试中,我发现将速度因子r设为100~200,滤波因子h设为0.01时,能有效平衡响应速度与平滑性。 -
扩张状态观测器(ESO)
这是ADRC的核心创新点。通过将系统总扰动扩张为新的状态变量,实现扰动实时观测。以二阶系统为例,其状态空间方程可表示为:code复制ẋ1 = x2 ẋ2 = f(x1,x2,w(t)) + bu其中f(·)包含未知动态和扰动。ESO将其重构为:
code复制ẋ1 = x2 ẋ2 = x3 + bu ẋ3 = h(t)新增的x3就是被估计的总扰动。
-
非线性状态误差反馈(NLSEF)
采用非线性组合取代传统PID的线性组合。典型配置如:matlab复制u0 = β1·fal(e1,α1,δ) + β2·fal(e2,α2,δ)其中fal()是非线性函数,通过α和δ调节非线性特性。
2.2 参数整定经验公式
经过多个项目的实践验证,我总结出以下参数整定规律:
| 参数类型 | 经验公式 | 物理意义 |
|---|---|---|
| ESO带宽ω0 | (3~10)/ts | 观测器动态速度 |
| 控制器带宽ωc | ω0/3~ω0/5 | 控制响应速度 |
| 非线性因子α | 0.5~0.75 | 误差权重分布 |
| 滤波系数δ | 0.01~0.1 | 抗测量噪声能力 |
重要提示:实际调试时应先确定ω0,再根据带宽比确定ωc。过高的ω0会导致对噪声敏感,而ωc过高则可能引发执行器饱和。
3. Simulink实现详解
3.1 无人机建模关键点
在Simulink中构建四旋翼模型时,需要特别注意以下几个子系统的实现:
-
动力系统模型
每个旋翼的推力与力矩计算:matlab复制% 电机模型 Thrust = kt * ω^2 Torque = km * ω^2 % 动力学耦合 U1 = b*(ω1^2+ω2^2+ω3^2+ω4^2) // 总升力 U2 = b*l*(ω4^2-ω2^2) // 滚转力矩 U3 = b*l*(ω3^2-ω1^2) // 俯仰力矩 U4 = d*(ω2^2+ω4^2-ω1^2-ω3^2) // 偏航力矩 -
姿态解算模块
推荐使用四元数表示法避免万向节锁问题:matlab复制q̇ = 0.5 * q ⊗ [0; ω_body]
3.2 ADRC控制器实现
在Simulink中搭建ADRC控制器时,可采用S-Function实现核心算法。以下是关键代码段解析:
matlab复制function [sys,x0,str,ts] = ADRC_Sfun(t,x,u,flag,beta)
switch flag
case 0 % 初始化
sizes = simsizes;
sizes.NumContStates = 3; % z1,z2,z3
sizes.NumDiscStates = 0;
sizes.NumOutputs = 1; % 控制量u
sizes.NumInputs = 2; % 参考输入和系统输出
sizes.DirFeedthrough = 1;
sys = simsizes(sizes);
x0 = zeros(3,1); % 状态初始值
str = [];
ts = [0 0];
case 1 % 连续状态微分
e = x(1) - u(2); % 观测误差
sys(1) = x(2) - beta(1)*e;
sys(2) = x(3) - beta(2)*fal(e,0.5,0.01) + beta(6)*u(1);
sys(3) = -beta(3)*fal(e,0.25,0.01);
case 3 % 输出
e1 = u(1) - x(1); % 跟踪误差
e2 = 0 - x(2); % 微分误差
sys = beta(4)*fal(e1,0.5,0.01) + beta(5)*fal(e2,0.5,0.01) - x(3)/beta(6);
end
end
function f = fal(e,alpha,delta)
if abs(e)>delta
f = abs(e)^alpha * sign(e);
else
f = e/(delta^(1-alpha));
end
end
3.3 参数调试技巧
通过多次项目实践,我总结了以下调试步骤:
-
先调ESO观测器
- 保持控制量u=0,仅运行ESO
- 逐渐增大β1,β2,β3直到观测状态能快速跟踪真实状态
- 典型初始值:β1=100, β2=300, β3=1000
-
再调NLSEF控制器
- 固定ESO参数,加入控制回路
- 从小到大调整β4,β5(对应kp,kd)
- 观察阶跃响应,调节至无明显超调
-
抗扰验证
- 在仿真中注入阶跃扰动
- 检查ESO对扰动的估计速度
- 必要时微调β3增强扰动抑制能力
4. 实测问题与解决方案
4.1 典型问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 高频抖动 | ESO带宽过高 | 降低β1,β2,β3 |
| 响应迟缓 | 控制器增益不足 | 增大β4,β5 |
| 稳态误差 | 扰动补偿不足 | 检查b0估值准确性 |
| 发散振荡 | 执行器饱和 | 加入抗饱和处理 |
4.2 实测经验分享
-
传感器噪声处理
在实际飞行测试中,IMU噪声会导致ESO估计抖动。建议:- 在ESO前加入一阶低通滤波
- 调整fal()函数的δ参数(建议0.05-0.1)
- 代码示例:
matlab复制% 改进的fal函数 function f = fal_improved(e,alpha,delta,noise_gain) dead_zone = noise_gain * delta; if abs(e)>dead_zone f = (abs(e)-dead_zone)^alpha * sign(e); else f = 0; end end
-
参数自适应调整
针对不同飞行模式(如悬停、高速机动),我开发了参数调度策略:matlab复制% 根据飞行状态调整带宽 if norm(omega) < 2 % 低速模式 beta = [80, 200, 800, 15, 20, 0.8]; else % 高速模式 beta = [120, 400, 1500, 25, 30, 0.6]; end -
执行器保护机制
实际项目中遇到过电机过载烧毁的情况,后来增加了:- 控制量变化率限制(du/dt < 1000 Nm/s)
- 电机指令平滑过渡处理
- 过流保护反馈环
5. 进阶应用:从单机到编队控制
将ADRC扩展到多机编队时,需要解决的关键问题是:
-
扰动传播问题
领航者受到的扰动会通过通信拓扑传播。我们的解决方案是:- 在跟随者ADRC中增加领航者扰动观测
- 通信协议中加入扰动补偿项
-
一致性控制算法
改进的编队控制律结构:code复制ui = ADRC_local + γ·Σ(ADRC_neighbor - ADRC_local)其中γ为耦合强度系数,建议初始值0.3~0.5
-
通信延迟补偿
实测发现超过50ms的延迟会显著影响编队稳定性。我们采用:- 基于ESO的延迟预测补偿
- 时间戳同步机制
这个项目最让我惊喜的是,当把ADRC应用到20架无人机的灯光秀编队时,即便在3-4级风况下,仍能保持厘米级的队形精度。这充分证明了自抗扰算法在复杂环境下的强大鲁棒性。
