四旋翼无人机的控制,绕不开两个老大难:一是模型的高度非线性和强耦合,二是传感器噪声带来的状态估计误差。最近我把分层滑模控制(SO-SMC)和扩展卡尔曼滤波(EKF)组合到一起,在Simulink里搭了一套完整的仿真验证环境,并且跟传统的PID-EKF方案做了全维度的对比。这篇就围绕这个四旋翼Simulink仿真项目,把SO-SMC-EKF和PID-EKF两条技术路线的原理、建模、仿真架构以及调参踩坑过程全部摊开讲清楚,给打算做控制算法对比或者正在被四旋翼仿真折磨的朋友一份可以直接参考的实操记录。
1. 项目整体设计与方案选型思路
1.1 为什么非要把这两种方案摆在一起比
做四旋翼控制算法验证,最怕的就是只谈理论不谈对比。单独实现一套滑模控制器,飞得再稳也说服不了人,因为没有参照系。我在这个项目里铁了心要做一个完整的横向对比,直接把SO-SMC-EKF和PID-EKF作为两个并行分支搭在同一套Simulink模型里。这样做的好处有三个:第一,两个控制器的输入信号完全相同,传感器噪声模型完全一致,排除了实验条件不一致带来的干扰;第二,切换对比只需要拨一个开关信号,不需要重新编译模型;第三,可以在同一组仿真结果图上直接叠加显示两条控制曲线,做报告或者发论文的时候素材足够直观。
选PID当基准是深思熟虑过的。现在工业界和学术界对四旋翼的飞控方案,90%以上还是PID及其变体,拿PID做对比基准最有说服力。而分层滑模这边选二阶滑模(Second-Order Sliding Mode)而不是普通一阶滑模,核心原因是普通滑模控制器的抖振问题在仿真里太明显了。纯一阶滑模在切换项的作用下,控制量输出会出现高频抖动,在离散仿真步长下这种抖振会被进一步放大,最终让执行器模型出现剧烈波动。二阶滑模通过把不连续项放到控制量的导数里,让控制量本身保持连续,从根源上缓解抖振。这个选型在后面仿真对比里带来了非常直观的差异。
1.2 四旋翼控制难在哪里
四旋翼是一个典型的欠驱动系统:四个螺旋桨的转速输入,却要控制六个自由度的位姿输出。横向运动必须通过先倾斜机身、改变推力向量的水平分量来实现,这就导致位置控制和姿态控制天然地耦合在一起。用行话来说,位置控制环的动态特性取决于姿态控制环的响应速度,姿态控制环一旦不够快,整个位置环就会发散。
另一个难点是动力学模型里的强非线性。旋转矩阵涉及欧拉角的三角运算,陀螺力矩效应包含角速度的叉乘项,空气阻力与速度的平方成正比。PID在这种强非线性系统里通常只能保证在某个工作点附近有效,一旦飞行状态偏离平衡点太远,线性化模型对应的PID参数就失效了。滑模控制的优势就在这里,它通过设计滑模面和切换控制律,让系统状态被强制约束在滑模面上,对匹配的非线性项和外部扰动具有天然的鲁棒性。这也是我在这个项目里重点验证的核心命题:在同样的风扰和传感器噪声下,滑模的鲁棒性到底比PID好多少。
1.3 EKF在链路里的角色
我在这套仿真里坚持要加EKF,不是画蛇添足。真实四旋翼的传感器输出是带噪声的,IMU里的加速度计噪声、陀螺仪漂移、GPS的位置抖动,这些都会直接影响到控制器读到的状态量。如果控制器里用的状态是理想值,那仿真结果本质上只是“算法在完美状态下的理论表现”,没有工程参考意义。EKF的作用就是在噪声环境下估计出平滑、稳定的状态,把真实系统中的状态观测问题和控制问题解耦开来。
EKF的设计也有讲究,后面会细说。放一个EKF在传感器和控制器之间,需要额外处理测量更新与预测更新的频率匹配问题,还要调噪声协方差矩阵。这部分的调参工作量一点不比设计滑模控制器小,而且它直接影响控制效果的好坏。很多做控制仿真的同学把EKF当成一个黑盒子塞进模型里,跑出来的曲线乱跳,第一个怀疑的就是控制器参数没调好,实际上相当一部分问题出在EKF的协方差矩阵和初始状态设置上。
2. 核心原理拆解:从动力学建模到控制律设计
2.1 四旋翼动力学模型的坐标系与状态方程
四旋翼建模第一步是确定坐标系统和状态向量。我采用的是常规的北东地(NED)惯性坐标系和机体坐标系组合方式,状态向量取12维:位置(x, y, z)及其导数、欧拉角(φ, θ, ψ)及其角速度。写出来就是:
[ \mathbf{X} = [x, y, z, \dot{x}, \dot{y}, \dot{z}, \phi, \theta, \psi, p, q, r]^T ]
位置动力学方程建立在惯性系下,推力向量通过旋转矩阵从机体系变换到惯性系;角速度动力学方程建立在机体系下,要考虑转动惯量矩阵和陀螺力矩。核心方程如下:
[ m\ddot{\mathbf{P}} = \mathbf{R} \cdot \mathbf{F}{thrust} + m\mathbf{g} - \mathbf{F}{drag} ]
[ \mathbf{I}\dot{\boldsymbol{\omega}} = -\boldsymbol{\omega} \times (\mathbf{I}\boldsymbol{\omega}) + \boldsymbol{\tau} ]
其中R是机体坐标系到惯性坐标系的旋转矩阵,F_thrust是机体z轴方向的升力合力,tau是滚转、俯仰、偏航三个通道的控制力矩。控制分配模块把三个力矩和一个总升力映射成四个电机的转速指令,标准的X型布局映射矩阵涉及电机到机臂的力臂长度和电机混控比。这些方程在Simulink里用Fcn模块逐个搭建即可,不难,但要注意旋转矩阵的欧拉角旋转顺序要和姿态控制器里的定义保持一致,我用的Z-Y-X(即先偏航、再俯仰、最后滚转)顺序。
2.2 分层滑模控制的结构设计与滑模面构造
分层滑模控制的思想很朴素:把系统控制结构分成两个层次,外层位置控制生成虚拟控制量(期望加速度),内层姿态控制跟踪外层的期望姿态角。外层不需要直接输出推力,而是输出期望的滚转角、俯仰角指令,这样就把欠驱动系统的控制问题转换成了“位置环控制”加“姿态环跟踪”的标准串级结构。
位置环的滑模面定义为:
[ \mathbf{s}_p = \dot{\mathbf{e}}_p + \mathbf{c}_p \mathbf{e}_p ]
其中e_p是位置误差向量,c_p是正定的对角增益矩阵。这个滑模面的物理意义是位置误差的收敛速度由c_p决定,c_p越大收敛越快,但过大会引起控制量饱和。实际取值时我会遵循一个经验法则——期望位置环的带宽是姿态环带宽的三分之一到五分之一,避免内外环动态耦合导致系统发散。
姿态环的滑模面设计考虑到四元数或欧拉角的微分关系,我这里用的是欧拉角空间的简化模型:
[ \mathbf{s}_a = \dot{\mathbf{e}}_a + \mathbf{c}_a \mathbf{e}_a ]
这里e_a是姿态角误差向量。二阶滑模的构造是在滑模面的导数里引入不连续项,即:
[ \dot{\mathbf{s}}_a = \mathbf{f}(\mathbf{X}) + \mathbf{g}(\mathbf{X})\boldsymbol{\tau} + \mathbf{d}(t) ]
控制律设计为:
[ \boldsymbol{\tau} = \boldsymbol{\tau}{eq} + \boldsymbol{\tau}{sw} ]
等效控制项tau_eq由系统模型反解得到,切换项采用超螺旋算法(Super-Twisting)的形式,包含一个关于滑模面的连续积分项和一个在滑模面导数域里的不连续项。这种形式的切换项在时间积分意义上消除了抖振,同时保持了对外部扰动的有限时间收敛特性。这是分层滑模控制较传统PID最有说服力的理论优势。
2.3 扩展卡尔曼滤波的滤波机理与状态观测
EKF的思想是对非线性系统做局部线性化。四旋翼的状态方程和观测方程都是非线性的,EKF每次预测和更新时都要计算雅可比矩阵,把非线性系统线性化到当前状态附近再做标准的卡尔曼滤波递推。滤波器内部做五步循环:状态预测、协方差预测、卡尔曼增益计算、状态更新、协方差更新。公式部分直接参考教科书即可,关键在状态模型的设计。
我在EKF里把状态向量设计为15维,在四旋翼12维状态的基础上额外加了3个陀螺漂移量:
[ \mathbf{X}_{ekf} = [x, y, z, \dot{x}, \dot{y}, \dot{z}, \phi, \theta, \psi, p, q, r, b_x, b_y, b_z]^T ]
加陀螺漂移的目的是让滤波器在线估计陀螺零偏,这个在实际IMU数据处理中是必须的,不然姿态估计会随着时间累积漂移。观测方程模拟GPS加IMU的融合场景,GPS提供位置和速度观测,加速度计提供比力观测,陀螺仪直接提供角速度观测。这个观测模型下,EKF的雅可比矩阵推导有相当多的工作量,但一旦搭好,后续改传感器配置就是改参数矩阵的问题。
2.4 控制与观测的取样策略问题
有同学在做仿真的时候产生过疑惑:为什么我加了EKF反而系统不稳定了?这个问题通常出在控制器的更新频率与EKF的更新频率不一致上。在Simulink里我采用的是多速率架构:控制器运行在500Hz,EKF的预测更新也运行在500Hz,但测量更新分开处理。GPS模拟为10Hz的慢速观测,IMU模拟为200Hz的快速观测。EKF内部维护两个不同的测量更新分支,GPS观测到了就走GPS更新流程,IMU观测到了就走IMU更新流程。这种多速率融合架构跟真实飞控的传感器调度逻辑是一致的,不是简单地在每个仿真步长里把全部观测塞进去。
多速率架构在后期的对比仿真里效果非常好,PID-EKF和SO-SMC-EKF都能获得稳定可靠的状态估计,但这也暴露了一个问题——如果EKF的观测模型和噪声参数设计得不合理,滤波发散时控制环再强也救不回来。所以建议在做控制器对比之前,先单独验证EKF的估计精度,再接入控制闭环,分步调试效率最高。
3. Simulink仿真环境的搭建过程与实操要点
3.1 仿真架构的整体模块划分
整个Simulink模型的模块划分我按信号流方向组织成六大块:参考输入生成器、控制器分支选择器、控制分配模块、四旋翼六自由度模型、传感器仿真模块、EKF滤波模块。每个模块用Subsystem封装,提供统一的数据接口。信号流方向从输入到输出单向流动,避免代数环问题。Simulink模型中如果有代数环,仿真速度会骤降,而且容易出现数值震荡,所以我在设计时注意了所有反馈回路都要经过一个单位延迟或状态量而非直接代数穿越。
参考输入生成器支持三种模式:悬停指令、定高圆周轨迹、预设的8字形轨迹。控制器分支选择器是一个多路开关,根据仿真参数控制信号选择SO-SMC-EKF或PID-EKF路径。四旋翼六自由度模型接的是控制分配模块输出的四个拉力指令,内部输出位置、速度、姿态、角速度12个状态量。传感器仿真模块在12个状态量上叠加高斯白噪声和随机漂移,模拟真实传感器的输出特征。
3.2 四旋翼模型与传感器噪声的参数配置
四旋翼模型参数直接影响控制器的设计和效果。我用的标准参数配置如下表所示:
| 参数 | 数值 | 说明 |
|---|---|---|
| 质量 m | 1.4 kg | 典型小型四旋翼质量 |
| 机臂长度 l | 0.225 m | 电机到机体中心距离 |
| 滚转惯量 Ixx | 0.021 kg·m² | X轴转动惯量 |
| 俯仰惯量 Iyy | 0.022 kg·m² | Y轴转动惯量 |
| 偏航惯量 Izz | 0.043 kg·m² | Z轴转动惯量 |
| 升力系数 kT | 1.2e-5 N/(rad/s)² | 电机转速平方到升力系数 |
| 扭矩系数 kQ | 2.0e-7 N·m/(rad/s)² | 电机转速平方到扭矩系数 |
传感器噪声配置要贴近实际IMU性能水平。加速度计的噪声方差设为0.01 m/s²,陀螺仪角度随机游走为0.001 rad/s,位置观测噪声为0.1 m,观测频率分别按上文的多速率策略设置。这些数值如果取太小,EKF的优势体现不出来;取太大,控制器的性能会被噪声主导,曲线难看。我的建议是根据你的目标对比场景来设置,如果论文重点是控制算法的鲁棒性对比,传感器噪声可以适当取中低水平,让控制器性能差异成为主导因素。
3.3 EKF模块的实现细节与S函数选择
EKF模块的实现我在Simulink里提供了两种途径:一种是用MATLAB Function模块写完整的EKF递推代码,另一种是直接用S-Function。我自己的做法是写了一个C-MEX格式的S-Function,因为仿真速度比MATLAB Function快得多,特别是跑对比实验时要连续跑几十次参数扫描,速度优势非常明显。
EKF模块里最核心的是两个雅可比矩阵的计算。状态转移矩阵F的雅可比是15x15矩阵,观测矩阵H的雅可比维度取决于当前是GPS更新还是IMU更新。这个矩阵推导建议用符号计算工具辅助生成,手算的话工作量太大而且容易出错。我在项目里用符号推导生成C代码后粘贴到S-Function里,整体调试时间节省了一大半。EKF初始协方差矩阵P0设为单位矩阵乘以一个缩放系数,Q矩阵设为对角线小值,R矩阵根据传感器噪声方差确定。整套参数在后面的调参环节里还需要根据实验效果微调,不是一成不变的。
3.4 仿真步长与求解器选择
仿真步长和求解器的选择是Simulink仿真里最容易忽视的细节。四旋翼的状态变化速度快,姿态环的响应带宽通常超过10Hz,如果仿真步长取得过大,离散化误差会被控制器的高增益放大,导致仿真结果出现高频振荡。我调试多次的经验是固定步长取1ms,即1000Hz仿真频率,求解器用四阶龙格-库塔(ode4)。有些同学为了省时间把步长调到5ms,跑同一个控制器得出的稳定性结论完全不同,这就是数值误差在作祟。
跑完一次仿真后,需要检查几个关键信号来确定数值稳定性:控制输入是否有高频振荡、位置误差是否单调收敛、EKF的标准化残差是否在±3范围内。如果标准化残差长时间超出±3,说明EKF的Q或R矩阵参数失衡了,需要重新调节。
4. 对比实验设计与结果分析
4.1 实验场景设定与性能指标选型
为了公平对比SO-SMC-EKF和PID-EKF,我设计了三个实验场景。第一个是定点悬停加脉冲风扰,悬停在(1, 0.5, 1)坐标点上方,在10秒时刻给x方向一个持续2秒的风扰脉冲,考验系统的抗扰恢复能力。第二个是定高圆周轨迹跟踪,追踪半径2米的圆形轨迹,考验连续信号的跟踪精度。第三个是面对称的8字形轨迹,带有加加速度的快速变向,考验控制器在加速动态下的跟踪性能。
性能指标选用四组:位置跟踪的均方根误差(RMSE)、控制能量(四个控制通道的平方积分)、超调量、稳态收敛时间。这四个指标兼顾了跟踪精度、能量消耗和动态响应的快速性。RMSE和控制能量作为表格式结果列出,超调量和收敛时间直接标注在响应曲线上。这种多指标评价能避免单一指标评价的偏差。
4.2 定点悬停响应对比
在悬停加风扰的场景里,两套方案的表现拉开了明显差距。SO-SMC-EKF对脉冲风扰的抑制非常迅速,位置偏移峰值约为0.18米,恢复时间大约在1.5秒左右。PID-EKF在同样的风扰下位置偏移峰值达到0.35米,恢复时间接近4秒。从姿态通道看,SO-SMC的姿态角变化幅度明显更小,说明滑模控制对扰动具有更强的抑制作用。但从波形细节上也能看到,PID-EKF在稳态时的姿态角波动更平滑,而SO-SMC存在微幅的高频等幅振荡,这就是滑模控制“抖振抑制后仍有残余”的体现。把抖振完全消除是做不到的,二阶滑模能做的只是把抖振幅值控制在可接受范围,这个需要在仿真图里跟读者说清楚。
EKF的作用在悬停场景中体现得很明显。对比有没有EKF的差异:去掉EKF直接拿带噪声的测量值控制,SO-SMC和PID控制器的位置输出都会有明显的等幅波动,这是把测量噪声当作真实状态来反馈导致的。加上EKF后,控制量的高频分量明显减少,执行器模型的磨损也能得到控制。EKF在这个场景里相当于隐藏在控制器背后的“稳定器”,效果非常直观。
4.3 轨迹跟踪性能对比
轨迹跟踪场景下的差异比悬停场景更清晰。8字形轨迹跟踪时,SO-SMC-EKF的跟踪RMSE大约是PID-EKF的30%-40%,特别是在轨迹拐点的地方,PID的跟踪误差会出现明显的一个尖峰,这是因为拐点处加速度突变,PID的线性控制模型无法快速适应动态变化,而滑模控制的强鲁棒性让误差被滑模面迅速拉回。总的控制能量方面,SO-SMC的能耗要高出PID约12%左右,这是因为滑模控制的切换项本质上是一种高增益控制,需要额外消耗能量来维持鲁棒性。这在做工程选型的时候需要考虑清楚:如果续航是第一位,PID更省电;如果抗扰性是第一位,滑模更有优势。
4.4 结果汇总表与指标解释
下表是三个实验场景下两组方案的关键指标对比汇总:
| 场景 | 指标 | PID-EKF | SO-SMC-EKF | 优势 |
|---|---|---|---|---|
| 悬停抗风扰 | 峰值偏移(米) | 0.35 | 0.18 | SO-SMC |
| 悬停抗风扰 | 恢复时间(秒) | 3.9 | 1.5 | SO-SMC |
| 圆周轨迹 | RMSE(米) | 0.089 | 0.041 | SO-SMC |
| 8字轨迹 | RMSE(米) | 0.142 | 0.053 | SO-SMC |
| 8字轨迹 | 控制能量(相对值) | 1.00 | 1.12 | PID |
从结果看,SO-SMC-EKF在跟踪精度和抗扰性方面全面优于PID-EKF,但代价是12%左右的额外控制能耗。这是一个很典型的“性能换能量”的权衡。在读结果的时候,只讲性能提升不讲能量消耗是不完整的,工程上从续航角度看这一点非常关键。
5. 调试过程与常见问题避坑手册
5.1 分层滑模控制器的参数调节经验
滑模控制器参数的调节经验,说多了都是泪。位置环增益c_p和姿态环增益c_a的设置需要进行多轮试错,核心准则参考内外环带宽匹配。我先固定姿态环的c_a,然后从低到高逐步调大c_p,观察位置阶跃响应。如果位置响应出现振荡,说明c_p相对于姿态环带宽太高,需要降低。如果阶跃响应太慢,需要提高c_p。有一个小技巧是直接看姿态指令信号,如果姿态角指令频繁进入饱和区,说明位置环给定的期望加速度太快,这时候要先增大滑模面的趋近律系数或者降低c_p。
趋近律系数k的选择直接影响抖振水平。k值太小,扰动到来时滑模面恢复慢;k值太大,控制量高频抖动加剧。调k值的正确做法是盯住控制量的功率谱密度图,找到抖动频段对应的幅值,逐步减小k值直到抖动幅值下降到可接受水平。在我这个项目里,最终k值约为理论计算值的60%,这多出来的余量就是给实际模型不确定性留的。
5.2 EKF不发散但精度差的调参方向
EKF在仿真里最常见的现象是滤波不发散但估计精度差。我遇到过的原因通常是Q矩阵数值设置太小,滤波器对模型的信任度太高,导致预测结果没有被测量值充分修正。这时候的表现是位置估计曲线滞后于真实位置曲线,姿态估计存在固定的偏置。解决办法是逐步增大Q矩阵中的过程噪声系数,让滤波器更信任测量值,观察估计曲线与真实曲线的贴合理度。反之如果估计曲线噪声大、波动剧烈,说明Q矩阵太大或者R矩阵太小,需要反向调节。
EKF还有一个隐蔽的坑是初始P0矩阵设置不当导致前期滤波瞬态过长。P0设置得太小会让滤波器前几十个采样周期的估计值严重偏离真实值,在闭环控制里可能直接导致控制器发生飞车。我的处理办法是P0对角线设为10倍的真实初值方差,而不是设成0,这样滤波器前期瞬态可以在几毫秒内收敛,避免了控制链路的初期冲击。
5.3 仿真发散和数值振荡的判断与处理
仿真跑着跑着突然数值爆炸,是Simulink仿真中绕不开的梦魇。第一步要定位是控制器发散还是EKF发散。最简单有效的排查办法是断开控制器反馈环,单独给EKF喂开环测量数据,看滤波器输出是否正常。如果开环没问题但闭环发散,问题几乎都在控制器的增益或滑模切换项上。如果开环EKF输出已经发散,问题出在EKF的雅可比矩阵推导或者协方差更新公式实现上。
另一个经常被忽略的地方是控制分配矩阵的符号方向。X型四旋翼的电机混控方向直接决定了滚转力矩的正负号,如果符号配反了,仿真必炸。我的排查技巧是分别对滚转、俯仰、偏航三个通道单独施加一个阶跃指令,观察机体姿态角是否朝期望方向转动,这一招能在五分钟内定位符号问题。
还有数值振荡的问题,当控制器增益过高时,离散仿真步长内控制量的变化幅度过大,会激发模型里的高频未建模动态。解决手段包括提高仿真步长精度、在控制器输出端加一阶低通滤波器、或者使用更为平滑的二阶滑模算法。我在项目里最终采用了三次轻滤波处理,兼顾了响应速度和控制量平滑度。
5.4 常见问题速查表
我把本次项目踩过坑比较多的点整理成了一个速查表,每次调参前我都会对照检查一遍:
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 位置误差振荡发散 | 位置环带宽高于姿态环 | 降低位置环增益或提高姿态环带宽 |
| 姿态角高频抖动 | 滑模切换项增益过大 | 降低切换项系数或改超螺旋算法 |
| EKF估计滞后真实值 | Q矩阵过小、滤波器过度信任模型 | 增大Q矩阵,降低R矩阵值 |
| EKF估计噪声大 | Q矩阵过大或R矩阵过小 | 降低Q矩阵范围,增大R值 |
| 控制量频繁饱和 | 指令加速度过大或增益过高 | 限制参考输入变化率、降低增益 |
| 前期瞬态震荡 | P0初始值设置不当 | 增大P0初值,集中在开始时求解 |
| 模型速度异常快 | 控制分配符号反了 | 检查电机混控方向,逐通道测试 |
这套速查表在我后续的几个仿真项目里反复使用,命中率相当高。尤其是EKF的Q/R矩阵失调问题,在刚上手EKF的人那里几乎必现。
6. 项目心得与后续扩展方向
这个项目做完以后,我对控制算法对比的理解比单纯调参数时深刻了很多。SO-SMC-EKF在性能上压制PID-EKF,这是理论早就预告过的结果,但实际跑出来的数据让我们有机会看到差距的具体量级:跟踪精度提升约60%-70%,抗扰恢复速度快两倍以上,代价是多消耗约12%的控制能量。这个“性能提升与能量消耗的平衡点”工程师视角的关键信息,不实际跑一遍是体会不到的。
对想复现或者扩展这套仿真的朋友,我建议顺着三个方向继续做下去。第一个方向是替换控制器,把二阶滑模换成终端滑模或者自适应滑模,核心算法框架不用动,只换控制器模块的内部逻辑,就能对比出不同滑模变体的优缺点。第二个方向是把EKF替换成无迹卡尔曼滤波(UKF)或粒子滤波,对比高阶非线性下的状态估计精度差异。UKF对强非线性系统的估计精度通常优于EKF,但计算量是EKF的数倍,这个对比在论文里很有看点。第三个方向是加入气动参数摄动,比如把模型里的升力系数在仿真中途突然改变10%,观察两种控制器在模型参数失配情况下的适应性差异,这个场景最能体现滑模鲁棒性的价值。
最后分享一个小经验:对比仿真实验最忌讳的是只放一条漂亮的响应曲线,而必须把对照组、误差带、扰动场景、能量消耗完整展示出来。把SO-SMC-EKF和PID-EKF的曲线叠在同一个坐标系里,配上扰动标志和性能指标表,这才是完整的对比论证链条。做仿真项目,图和数字本身不会骗人,但只看图不看数字会骗自己。