☰
四旋翼PID控制论文复现指南:从Simulink建模到仿真调参与参数整定
2026/10/21 9:09:46 网站建设 项目流程

有的论文在 Simulink 里看起来模型很规整,但自己动手复现时却各种飞不起来、参数调不动、结果对不上。如果你正准备做“基于 Simulink 的四旋翼 PID 控制”这类复现工作,这篇文章值得认真看完。我会从怎么读懂期刊论文里的模型公式开始,讲到 Simulink 里模块怎么搭、PID 怎么整定、仿真结果怎么和论文数据比对,最后把我踩过的坑一并列出来。整个复现链路走通后,你自己也能动手改模型、加扰动、换控制器做扩展实验。

1. 复现前的准备工作:先读透论文再动手搭建

1.1 复现四旋翼控制论文时,最先要确认的三件事

拿到一篇四旋翼 PID 控制相关的期刊论文,先别急着打开 Simulink。我遇到过不少同学花两天把模型搭好了,结果回头才发现论文里用的坐标系定义和自己理解的不一样,导致所有姿态反馈符号都是反的,仿真直接发散。复现的第一步,一定是把论文里这三件事抠清楚:

  • 坐标系定义:绝大多数四旋翼论文采用“地球惯性坐标系 + 机体坐标系”的组合,但具体到姿态角定义,有的是按“Z-Y-X”欧拉角顺序,有的是按“Z-X-Y”顺序,还有的用四元数。这直接决定了旋转矩阵的写法,也决定了 Simulink 里姿态解算模块的输入输出顺序。
  • 控制结构图:论文要么给出 Simulink 框图,要么给出“位置环 + 姿态环”的串级控制结构图。要确认是串级 PID(外环位置、内环姿态),还是单环 PID;确认期望输入是姿态角指令还是角速度指令;确认控制器输出是升力 + 三个力矩,还是直接给四个电机的 PWM 等效值。
  • 模型参数表:质量、臂长、转动惯量、升力系数、阻力系数这些参数,必须和论文里表 XX 一一对应。很多论文会隐藏一部分参数,或者单位写法不统一,比如重力加速度用的是 9.81 还是 9.8,质量精确到小数点后几位,这都会显著影响仿真曲线的幅值。

我自己的习惯是:先建一个“参数速查表”,把论文里的变量名、物理含义、数值、单位全部列出来,对照确认后再开始建模。宁可在这里多花半小时,也远好过仿真发散后回头一页页翻公式。

1.2 坐标系与欧拉角的约定问题,复现中避不开的“坑中坑”

四旋翼论文里最常见的坐标系约定是:惯性系(通常取北东地 NED 或东北天 ENU)和机体系(原点在质心,X 轴指向机头方向,Y 轴指向右侧,Z 轴向下或向上)。这里出现分歧的往往是:重力加速度的方向。如果你用的是 NED 系,重力在 Z 轴是正方向(向下);如果你习惯 ENU,重力就是负 Z。Simulink 里搭建运动学方程时,如果只抄公式但没注意坐标系正负号,结果就是位置一路向下飘,怎么调 PID 都拉不回来。

欧拉角的旋转顺序也容易翻车。很多论文写“滚转角 φ、俯仰角 θ、偏航角 ψ”,但并没有明确说是按哪种顺序旋转的。常见的 Z-Y-X 顺序(先偏航、再俯仰、最后滚转)在航空领域比较普遍,对应的旋转矩阵也最常用。如果是 Z-X-Y 顺序,虽然最终效果在很多工况下差别不大,但在大姿态角仿真时,对比论文曲线的细微差异就能看出来。为了稳妥,我会先在脚本里手动验证一遍论文给的旋转矩阵是不是单位正交阵,行列式是否为 1。这一步数值验证能快速发现公式抄写错误,也是复现工作里成本最低的校准手段。

2. 四旋翼动力学模型:从数学公式到 Simulink 模块化实现

2.1 核心方程组拆解:位置方程、姿态方程、控制分配

四旋翼刚体动力学一般分为平动和转动两部分。平动方程通常写成:

m * ddot(P) = R * (T_total) + G

其中 P 是惯性系下的位置向量,R 是机体坐标系到惯性系的旋转矩阵,T_total 是四个旋翼总升力在机体 Z 轴方向上的力向量,G 是重力向量。转动方程则写成:

I * dot(omega) + omega × (I * omega) = M

这里的 omega 是机体角速度,M 是外力矩(滚转力矩、俯仰力矩、偏航力矩)。在做 Simulink 建模时,我的建议是不要尝试用一个 MATLAB Function 模块把整个方程组一把梭写进去,虽然那样看起来代码量少,但调试时根本看不清中间量。更实用的做法是:用积分器模块 Integrator 作为核心状态存储单元,把方程拆分成分步计算。

为什么优先用 Integrator 而不是传递函数?因为四旋翼模型本质上是强非线性、强耦合的,传递函数只能用于线性化后的局部模型,而积分器配合乘法器、三角函数模块可以直接表达完整非线性。特别是涉及到旋转矩阵 R 时,用 Simulink 里的矩阵运算模块(或 MATLAB Function 只写旋转矩阵)会比纯传递函数精确得多。

控制分配部分也容易被忽略。PID 控制器的输出如果是总升力 U1、滚转力矩 U2、俯仰力矩 U3、偏航力矩 U4,那么需要反解四个电机的转速。反解公式在论文里一般长这样:

F_i = k * omega_i^2

四个电机的力与力矩线性组合,最终形成一个 4×4 分配矩阵。这里要注意:升力系数 k 与力矩系数 b 的量纲和单位。如果论文里的力单位是牛顿,转速单位是 rad/s,那么系数就按国际单位写。但有些论文用转/分钟,直接抄进去会让升力放大几百倍。

2.2 Simulink 模型分层搭建:我把模型拆成四层来跑

实际搭建 Simulink 模型时,我会把整个仿真分成四个层级,每一层在单独的子系统或子系统中用 Goto/From 标签传递信号,方便排查问题:

第一层是“输入层”,包括遥控器指令信号源、预设轨迹生成器或阶跃信号发生器,输出期望位置、期望偏航角。第二层是“控制器层”,负责位置外环 PID 和姿态内环 PID,输出总升力和三个力矩指令。第三层是“控制分配与执行器层”,把 U1~U4 映射到四个电机的拉力,再叠加电机一阶惯性环节(很多论文会简化成纯比例,但加入小时间常数更接近真实)。第四层是“刚体动力学层”,实现位置方程和姿态方程,输出位置、速度、姿态角、角速度反馈到控制器层。

每一层的输入输出接口尽量用 Bus 对象定义,这样信号线整理起来非常清晰。刚开始建模时,我习惯给每个模块加“手动开关”,例如在动力学输出端加一个信号选择器,可以一键切换“纯模型开环”和“闭环控制”两种模式。这给我调试时带来极大便利:控制器还没调好时,可以先验证开环模型响应是否符合物理常识(比如给定恒力,位置积分曲线是否平滑)。

在模块参数设置上,Simulink 的求解器类型我选用变步长 ode45,相对误差设为 1e-6。四旋翼模型的转速通常上千,虽然仿真速度不快,但精度能保证。如果把步长设得太大(比如固定步长 0.01),姿态环很容易出现高频振荡的假象,让人误以为是 PID 参数问题,其实是数值积分误差。

3. PID 控制器设计与参数整定:从理论公式到 Simulink 实现

3.1 内环姿态 PID 与外环位置 PID 的配合逻辑

串级 PID 是四旋翼控制论文里的主流方案:外环位置 PID 输出期望横滚角和期望俯仰角,内环姿态 PID 再对期望姿态角做跟踪。有些人会问,为什么位置环不直接输出推力倾角而是先转成姿态角?因为四旋翼是一个欠驱动系统,水平方向平移必须通过倾斜机体产生水平分量来实现,所以位置控制本质上是在规划“倾斜多少度”的问题。

在设计里,外环位置 PID 一般形式为:

theta_des = Kp_x * (x_des - x) + Kd_x * (vx_des - vx) + Ki_x * integral(x_err)

这里算出来的 theta_des 并不是直接给电机,而是作为内环姿态角的期望值。内环姿态 PID 则对角度误差做比例、积分、微分控制,输出滚转力矩。改变期望俯仰角就会改变机体前倾角,进而产生水平加速度,完成位置跟踪。

这个串级结构有一层潜在问题:内环的动态响应速度必须远快于外环,否则两个环路会互相激励振荡。我通常在整定时先保证内环带宽大约是外环带宽的 5 到 10 倍。简单判断方法:给姿态环一个 5° 阶跃,如果响应时间在 0.1 秒数量级,而位置环响应时间在 0.5 到 1 秒数量级,说明时间尺度分离是合理的。

3.2 PID 参数整定的顺序与初始值选取

串级 PID 的整定顺序必须是“先内后外,先 P 后 D 再 I”。这个顺序不能再反了。我第一次复现时直接同时调四个环路的九个参数,结果根本分不清是哪个环在振荡。具体做法:

  1. 先将所有微分项和积分项置零,只保留比例项。内环姿态 P 从很小的值开始(比如 1 到 2),逐渐增大,直到姿态响应出现约 10% 到 20% 的超调。这个“临界比例”附近可以作为内环 P 的基础值。
  2. 加入微分项抑制超调。微分项不宜过大,否则高频噪声会被放大。在 Simulink 里,我通常在微分环节后加一个低通滤波,滤波时间常数取 0.01 到 0.05 秒,效果非常明显。
  3. 最后加积分项消除稳态误差。如果仿真中存在恒定风扰或电机模型不对称,积分项能把静态误差压到接近零。但要特别注意积分饱和的问题,后面我会详细说。

参数初值的估计也有一套“物理直觉法”。拿内环姿态角 PID 来说,力矩与角加速度的关系是力矩除以转动惯量等于角加速度。如果 Ixx = 0.01 kg·m²,那么要达到 10 rad/s² 的角加速度,需要 0.1 N·m 的力矩,对应的角度误差如果是 0.1 rad,比例增益 Kp 约等于 10。这是量级参考,真正数值还得靠仿真微调。

实测中常用的一组初始参数范围我可以给出来作为参考。姿态内环:Kp 在 5~15,Kd 在 0.1~0.5,Ki 在 0.05~0.2。位置外环:Kp 在 0.5~2,Kd 在 0.3~1,Ki 在 0.01~0.05。不同论文的物理参数差别会让这些范围偏移一两倍,但量级基本不会跑到几百。

3.3 饱和与抗积分饱和处理,一个小细节解决大麻烦

真正常见的 PID 失控原因并不是参数不够好,而是“积分饱和”。当期望位置突变更大时,误差积分会迅速累积到很高的值,即使实际位置已经到达目标,这个“惯性积分”还会继续推动控制器输出,造成很大的超调甚至发散。

处理积分饱和的办法在 Simulink 里很直接:给积分器加一个输出限幅(saturation),或者使用“条件积分”策略——当控制器输出达到饱和边界时,冻结积分器的累加。实现方式可以在积分环节前加一个 Switch 模块,判据是控制量是否在限幅范围内。这一步看似小修改,但在大阶跃信号下的效果立竿见影。实验对比中,没加抗饱和的模型在 1 米阶跃目标下会冲出 0.4 米再回来,加完后超调直接降到 0.1 米以内。

4. 仿真过程与结果验证:让模型“跑起来”并对齐论文

4.1 先做悬停、再拉阶跃:把仿真流程固定下来

我把仿真验证流程固定为三步。第一步,模型零输入(四个电机转速相等)时跑 5 秒,观察位置、速度是否漂移。正常的动力学模型应该基本稳定,如果位置曲线向上或向下持续漂移,检查重力方向和升力方向。第二步,给一个悬停指令,也就是期望位置为原点,期望偏航角 0°,检验 PID 是否能把位置拉回并稳定。悬停是最能暴露模型符号错误的场景。第三步,给 X 方向一个 1 米阶跃期望位置,观察响应曲线是否平滑、是否快速稳定无振荡。

在做这三步时,我会把示波器 Scope 换成数据记录模块 To Workspace,把时间序列数据存到 MATLAB 工作区,方便后续做数值分析或画图。论文复现时,很多时候需要把仿真曲线与论文截图里的曲线叠在一起对比,这时数据的数值导出就很重要。我会在 To Workspace 里设置采样时间为 0.01 秒,这样画出来的曲线足够平滑,又不至于数据量过大。

对于论文里经常给出的“X 方向位置响应”曲线,我一般会关注三个指标:上升时间(从 10% 到 90%)、超调量(峰值与终值之差除以终值)、调节时间(进入 ±5% 误差带后不再出去)。如果这些指标和论文给出的表格吻合,说明复现已经基本成功;如果差异很大,就要回头找参数或建模上的问题。

4.2 论文数据比对时容易忽略的三个变量

论文里的曲线往往是特定仿真条件下的结果,复现时如果环境设置不一样,曲线就不可能完全一致。我总结出三个最容易忽略的变量:

  • 初始状态:论文是否说明初始位置为原点、初始速度为 0、初始姿态角为 0?如果没有说明,默认要按“零初始状态”来设置,但有的仿真会故意加一个初始偏航角。
  • 电机执行器延迟:有的论文把电机响应简化成“比例环节”,有的会加入一阶惯性环节,时间常数可能取 0.02 秒甚至更大。这个时间常数会改变相位滞后,直接影响 PID 可用的最大增益。
  • 采样时间与控制频率:数字 PID 在 Simulink 里通常要固定步长(比如 0.01 秒),而连续 PID 则使用变步长。如果你的仿真模型用的是连续 PID,而论文实际上是离散 PID,那参数可能就有本质差异。

我在复现某篇论文时遇到过这样的情况:论文里的位置曲线上升时间约为 0.8 秒,超调约 15%。我仿真出来的上升时间只有 0.5 秒,超调却高达 35%。排查后发现论文里电机模型加了 0.03 秒惯性延迟,而我用的是纯比例。加上了这个延迟环节后,曲线基本和论文吻合。差异就出在执行器延迟上,这就是典型的“模型结构不同步”导致的结果偏差。

5. 常见问题排查与避坑实录:那些一开始就让人头疼的问题

5.1 仿真直接发散,先检查这五处

仿真一跑就发散,这是复现过程里最常见的情况。根据我自己的经验,优先按这个顺序排查:

  • 旋转矩阵方向反了:R 是“机体到惯性”还是“惯性到机体”,写反的话升力分量反向,姿态和位置必然发散。
  • 重力方向或大小错误:NED 系下重力为正,ENU 系下为负,不要抄了公式但坐标系没换。
  • 积分模块初始值:角速度初始值如果设成一个不合理的大数,积分很快爆掉。初始化最好全部置零。
  • 控制量符号反了:期望姿态角与实际姿态角相减时,如果顺序写反(actual - desired),反馈就变成了正反馈,相当于在给系统加能量。
  • 求解器步长过大:固定步长超过 0.005 秒甚至 0.01 秒,在姿态快速变化时误差很大,表现出来就是发散或高频振荡。

我遇到过最隐蔽的问题是“单位不统一”。论文里升力系数用的是 N/(rad/s)²,但我用了一个数值对应 N/(rpm)² 的系数,结果升力放大了约 100 倍,仿真直接飞出了上千米。这个教训让我后来建立参数表时,必须把“单位转换关系”单独列一列,比如 rad/s 与 rpm 的换算关系 1 rad/s ≈ 9.55 rpm。

5.2 仿真结果和论文结果对不上,从这几个方向找原因

即使模型不发散,曲线和论文对不上也让人头疼。我的排查思路优先级是:

  1. 先对比“控制结构”是否一致:串级还是单级,位置环输出是角速度还是角度,控制分配矩阵是否和论文一致。
  2. 再对比“参数数值”是否有量级误差:惯量、臂长、质量、升力系数、电机时间常数。
  3. 然后对比“控制器形式”:理想 PID 还是带限幅的 PID,微分项是否加滤波器,积分是否抗饱和。
  4. 最后对比“输入信号”:阶跃信号的幅值、时间点、斜率(有没有加斜坡过渡)。

有些论文图里的曲线是从某个特定的非线性仿真软件里导出的,比如很多飞控开发者会用硬件在环仿真或 ROS 仿真工具,而 Simulink 模型的建模细节不可能完全复现,这时候曲线有微小差异是可以接受的。关键是观察“趋势一致性”:超调量是否在相同水平、振荡频率是否接近、稳定时间是否在同一量级。只要这些定性特征一致,复现工作就算合格。

5.3 仿真速度太慢,影响参数调试效率怎么办

四旋翼模型的 Simulink 仿真速度有时很慢,特别是使用了变步长高精度求解器。为了提升调试效率,我会采用几个技巧:

  • 在整定参数阶段,使用固定步长 0.005 秒,求解器选 ode4(四阶龙格库塔)。精度比变步长略低,但仿真速度大幅提升,参数趋势判断完全够用。
  • 关闭示波器显示。Scope 模块在仿真时实时绘制会消耗大量资源,尤其是数据点多的时候。我会改为 To Workspace 记录数据,仿真结束后用 MATLAB 统一画图。
  • 减少不必要的示波器数量。可以把多个信号通过 Mux 合并进一个 Scope 模块,或者直接记录到工作区后再画子图。
  • 如果模型特别复杂,考虑把刚体动力学方程写成 MATLAB Function,这样在累积步数很多时反而比纯 Simulink 模块块链执行效率更高。

经过这些优化,一个 20 秒仿真通常能在几秒内完成,参数整定效率提升非常明显,我强烈建议在做复现工作时优先考虑。

6. 复现完成后还能做什么:改造、扩展与深化

复现论文只是第一步,做完基线复现之后,我会建议立刻做三件扩展工作。第一,给模型加入“风扰”模块,用随机信号或者常值风模拟野外环境,再看 PID 是否能保持稳定。这一步能验证控制器的鲁棒性,也是很多论文避而不谈但实际工程中非常关键的部分。第二,把连续 PID 改成离散 PID,在 Simulink 里用离散模块重新搭建,设置不同的采样时间,看看控制性能如何变化,这对接实际飞控代码非常有帮助。第三,把 PID 换成更高级的控制器(比如滑模、自抗扰、模型预测),在同一个模型上做横向对比,这也是很多论文后续章节的常见内容。

扩展时要注意的是:原始论文的模型往往为了研究主线做了大量简化,比如忽略空气阻力、忽略电机响应、假设惯量为常数。扩展实验时要明确自己是在“简化模型”上做改进还是换了更精细的模型。我个人的经验是,先保留原始模型跑好基线,再逐步增加复杂环节,每一步增加后都对比一次前后曲线,这样能清楚知道新增环节对控制性能的影响有多大,而不是一股脑升级模型后根本不知道差异来源。

从复现到扩展的全过程,Simulink 的价值在于“可视化”和“模块化”,但真正让人成长的是动手调试中积累的对物理模型、控制结构、数值求解的直觉。希望这篇文章对你做四旋翼 PID 控制论文复现有所启发。最后分享一个小技巧:每次修改模型前,先给不同版本命名并保存(比如 v1 不带电机延迟、v2 带电机延迟),方便随时回退对比,这个小习惯在反复调试、查找差异原因时特别省心。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询