
很多人一看到“期刊论文复现”就觉得头大觉得那是大佬才能干的事。其实把论文里的算法跑起来没有想象中那么玄乎。尤其像四旋翼无人机PID控制这种经典到不能再经典的方向论文里的仿真结果大多就是用Simulink搭个模型跑出来的你完全可以在自己电脑上把它复现出来还能顺手改进参数跑出一套比原文还漂亮的响应曲线。这篇我打算用一篇期刊论文复现的完整过程为线索把从建模、控制器设计到调参、仿真验证的每一步都拆开讲清楚。你会看到模型怎么搭、PID参数怎么调、仿真发散怎么查原因以及那些论文里不会写但实操中几乎必踩的坑。无论你是刚接触无人机控制的本科生还是正在做毕设、找课题的人这套流程都可以直接拿去参考。1. 复现前的破题论文到底想做什么拿到一篇四旋翼PID控制的论文别急着打开Simulink就开始拖模块。先花半小时把论文读透弄清楚作者的物理模型长什么样、控制目标是什么、用了什么简化假设。这几件事没搞明白后面搭出来的模型大概率是“形似而神不似”。1.1 先吃透论文的物理模型和假设典型的四旋翼无人机论文物理模型几乎都是同一个底子一个刚体受四个旋翼的升力和力矩作用。但由于作者学校、期刊、研究侧重点不同具体的方程写法会有差异。比如有的论文把空气阻力也写进去有的干脆忽略有的把电机当成一阶惯性环节有的直接认为升力响应是瞬时的这些细节直接影响你后面搭模型的复杂程度。我当时复现的那篇论文核心思路很朴素外环控制位置内环控制姿态位置环输出的期望姿态角送给内环内环用三个独立的PID通道控制roll、pitch、yaw角。这是四旋翼控制里最经典的分层架构几乎所有入门期刊论文都是这个路子。难点不在于架构本身而在于论文里往往只给出控制框图不给Simulink模型细节你要自己把每个模块用Simulink元件搭出来。建模这一步建议先在纸上把四旋翼的六自由度运动方程写出来。这里有个常见的起点版本位置动力学NED或ENU坐标系都可以关键是要跟论文一致 [ m\ddot{x} (cos\phi sin\theta cos\psi sin\phi sin\psi) \cdot U_1 ] (U_1) 是四个电机升力总和(m) 是机体质量三个欧拉角(\phi、\theta、\psi)分别对应roll、pitch、yaw。姿态动力学假设小角度近似或者直接用完整欧拉方程看论文怎么写 [ \ddot{\phi} \frac{I_{yy} - I_{zz}}{I_{xx}} \dot{\theta}\dot{\psi} \frac{U_2}{I_{xx}} ] [ \ddot{\theta} \frac{I_{zz} - I_{xx}}{I_{yy}} \dot{\phi}\dot{\psi} \frac{U_3}{I_{yy}} ] [ \ddot{\psi} \frac{U_4}{I_{zz}} ] 其中(U_2、U_3、U_4)是三个轴的力矩控制量(I_{xx}、I_{yy}、I_{zz})是三轴转动惯量。这一步其实挺花时间的但是值得。把方程写在纸上能逼你把每一个变量、每一个符号都搞清楚后面拖Simulink模块时就知道哪个信号连到哪里而不是瞎猜。1.2 确定你要复现的具体指标论文复现最容易翻车的点是你不知道“复现到什么程度算成功”。有的论文给的是阶跃响应曲线有的给的是轨迹跟踪曲线有的直接甩几个性能指标表格。你需要明确目标才有办法判断自己的模型跑得对不对。我当时给自己定了三个具体目标悬停控制初始位置偏离目标点若干米看位置环能否收敛回目标点。姿态阶跃跟踪给定30度俯仰角阶跃信号看姿态角能否无超调或小超调地跟上去。定高控制给定高度目标值看高度环在扰动下能否稳定稳态误差能不能压到可接受范围。这三个目标覆盖了大部分四旋翼PID论文的仿真部分。定了目标之后复现就不是“把模型搭出来”这种模糊任务了而是“模型搭出来之后输出曲线与论文曲线趋势一致、性能指标达标”这种可验证的任务。2. 建模与PID控制器的设计思路很多同学一开始学PID就陷进“调参”的泥潭其实对于四旋翼这种多通道强耦合的系统单纯调参而不理解模型结构基本等于瞎调。这一节先把控制器设计的骨架理清楚然后再进入模型搭建。2.1 为什么非得是“外环位置-内环姿态”结构四旋翼是一个欠驱动系统你没有能力直接独立控制四个自由度。你手上只有四个控制量总升力和三个力矩但系统有六个自由度三个位置三个姿态。所以必须设计一种策略用水平方向的位置误差去生成期望的roll、pitch角再由内环把实际姿态角控制到期望值。这个过程很像“你开车进停车场”的逻辑你不可能直接控制车辆横向位移你控制的是方向盘姿态通过方向盘让车身偏转车辆才会横向移动。这就是外环位置误差转化为内环姿态期望的直观含义。在Simulink里的反映就是位置环PID的输出是期望姿态角通常是roll和pitchyaw单独给目标值这个期望姿态角喂给姿态环PID姿态环PID的输出是三个力矩(\tau_\phi、\tau_\theta、\tau_\psi)再加上总升力(U_1)一起进无人机动力学模型。2.2 PID控制器的离散化与输出限幅论文里的PID通常写的是连续时间形式 [ u(t) K_p e(t) K_i \int e(t)dt K_d \frac{de(t)}{dt} ] 但Simulink仿真里实质是数字求解器在跑数值解所以PID模块内部是按离散方式工作的。你要注意几点第一PID模块的采样时间建议设置为与控制器更新频率一致比如0.01秒也就是100Hz。这个频率模拟的是飞控板上常见的控制循环频率不要设得太低否则会出现仿真结果与连续系统差异很大的情况。第二必须加输出限幅。四旋翼的力矩和升力都是有限制的电机转速有上下限对应升力上限和力矩上限。如果PID输出不做限幅模型里可能出现“电机输出负升力”这种物理上不合理的状态。大部分论文不写这个细节但复现时必须自己加上。我一般把(U_1)限制在0到满油门对应的最大升力力矩限制在最大力矩的±100%。第三积分环节必须考虑抗积分饱和。当输出达到限幅值时积分项还在继续累积会导致响应迟钝甚至等参考值变化时系统半天反应不过来。处理方法是在PID模块内部启用“Anti-windup”或者给积分器加限幅。Simulink自带的PID Controller模块可以直接勾选限制积分输出或者用条件积分法当输出饱和时冻结积分累加。2.3 初始调参思路先内环后外环四旋翼的双闭环PID调试顺序跟剥洋葱一样必须由内到外。先让姿态环稳定再去调位置环。原因很简单位置环的输出是姿态环的输入姿态环不稳定位置环闭环时看到的输入就是“噪声级”的怎么可能调得好。具体做法是先断开位置环给姿态环一个固定的期望姿态角阶跃信号比如期望roll角从0跳变到10度观察实际roll角能不能快速跟上、超调是否可接受。姿态环调好后再合上位置环给期望位置阶跃观察收敛情况。初始参数可以依据经验给一个估计然后根据响应曲线微调姿态内环P值可以先试小值比如2到5之间太大会出现高频抖动太小则响应太慢。I值从0.01左右开始试探主要用于消除稳态误差。D值用来抑制超调但过大会引入噪声敏感尤其在Simulink数值仿真中表现为高频振荡。上面说的都是“手感”具体数值跟模型参数强相关你的四旋翼质量、转动惯量不同PID参数差距会非常大。所以不要迷信网上某个“万金油”参数一定要根据你的模型特性去调。2.4 参数的“为什么”从模型特性倒推PID初始值其实初始PID参数是可以推算的。四旋翼roll、pitch通道的简化模型近似为一个二阶积分系统传递函数大概是(1/(I_{xx}s^2))。如果你知道转动惯量(I_{xx})就能把系统的自然频率和阻尼比与PID参数联系起来。举个例子如果(I_{xx}0.01\ kg·m^2)你希望姿态环的带宽在5rad/s左右那么临界增益大致在(K_p I_{xx} \cdot \omega_n^2 0.01*25 0.25)这个量级。当然这是单环理想情况实际情况有耦合、有延迟所以我会把这个值放大一些起步看响应再微调。这个推算过程极其有用。它让你明白PID设计不是纯玄学而是有明确动力学依据的。这也是期刊论文里不会反复强调、但工程上非常受用的部分。3. Simulink模型搭建全过程前面讲了一堆概念现在进入动手阶段。整个Simulink模型分为三块期望值生成、控制器、四旋翼动力学模型。我建议采用自上而下的结构把模型分成几个子系统而不是把所有逻辑堆在一个图里那样后期调试和排查问题会极其痛苦。3.1 动力学模型MATLAB Function还是Simulink积分器链四旋翼动力学建模在Simulink里有两种主流做法做法一直接用Simulink的积分器模块把加速度、速度、位置一级一级积分出来。优点全是原生模块信号流向一目了然适合教学演示。缺点公式一变就要重新接线改结构麻烦。做法二用MATLAB Function模块写动力学方程组。优点方程跟论文一一对应改参数、换公式只需改代码后期做蒙特卡洛参数扫描非常方便。缺点代码里面有bug时不好调试需要一定的MATLAB编程基础。我复现论文时用的是做法二。原因是论文里涉及非线性项陀螺效应项、交叉耦合项等用代码写方程比拖模块直观得多。MATLAB Function内部的核心代码逻辑大概是这样function [x_dot, y_dot, z_dot, phi_dot, theta_dot, psi_dot] quad_dynamics(state, U1, U2, U3, U4, params) % state: [x, y, z, phi, theta, psi, vx, vy, vz, p, q, r] % U1: 总升力, U2: roll力矩, U3: pitch力矩, U4: yaw力矩 % 提取状态 phi state(4); theta state(5); psi state(6); % 旋转矩阵从机体坐标系到大地坐标系 % 这里采用ZYX欧拉角顺序 R [cos(psi)*cos(theta), cos(psi)*sin(theta)*sin(phi)-sin(psi)*cos(phi), cos(psi)*sin(theta)*cos(phi)sin(psi)*sin(phi); sin(psi)*cos(theta), sin(psi)*sin(theta)*sin(phi)cos(psi)*cos(phi), sin(psi)*sin(theta)*cos(phi)-cos(psi)*sin(phi); -sin(theta), cos(theta)*sin(phi), cos(theta)*cos(phi)]; % 位置加速度在惯性坐标系下 accel [0; 0; U1/params.m] - [0; 0; params.g]; accel_xyz R * accel; x_dot state(7); y_dot state(8); z_dot state(9); % 姿态角速率与机体角速度的关系欧拉运动学方程 p state(10); q state(11); r state(12); phi_dot p q*sin(phi)*tan(theta) r*cos(phi)*tan(theta); theta_dot q*cos(phi) - r*sin(phi); psi_dot q*sin(phi)/cos(theta) r*cos(phi)/cos(theta); % 角加速度简化的欧拉方程忽略陀螺效应 p_dot (params.Iyy - params.Izz)/params.Ixx * q * r U2/params.Ixx; q_dot (params.Izz - params.Ixx)/params.Iyy * p * r U3/params.Iyy; r_dot (params.Ixx - params.Iyy)/params.Izz * p * q U4/params.Izz;这段代码的关键在于旋转矩阵和角速度到欧拉角速率的变换这也是四旋翼动力学中最容易出错的地方。如果你的论文坐标系定义不同比如用的是NED而不是ENU矩阵里的正负号要跟着调否则后面所有的仿真结果都会偏。3.2 控制器模块内部结构控制器模块我用一个大的MATLAB Function实现内部按位置环和姿态环分层。输入是期望位置、期望yaw角、当前状态向量输出是U1到U4四个控制量。位置环的PID逻辑是计算期望位置和当前位置的误差分别对x、y、z三个通道做PID运算。其中x通道的输出经过一个适当换算得到期望俯仰角y通道得到期望横滚角z通道的输出直接作为升力分量。姿态环的PID逻辑把外环输出的期望角度限制在合理范围比如正负30度与当前姿态角度做差分别经过三个PID得到三个力矩命令。这里有个容易被忽略的细节位置环PID的输出单位不是角度而是“加速度需求”你需要手动把它变成角度。常见做法是通过反正切函数换算或者考虑小角度假设直接按比例缩放。论文里如果写了线性化控制律你就照着论文来如果论文用的是反步法、滑模法之类的非线性方法那PID只是内环外面还要包一层地外环控制律复现复杂度会高不少。3.3 仿真参数设置和积分器选择Simulink的求解器设置是个大坑。如果你用的求解器步长太大模型跑出来会发散但你以为是自己PID调得不好或者跑出来曲线很平滑但实际上数值精度已经差到完全不可信。我个人复现四旋翼模型时使用变步长求解器如ode45或ode15s最大步长设置为0.001秒左右对应1000Hz的物理仿真频率。虽然这会拖慢仿真速度但四旋翼是刚体动力学模型姿态角速率变化很快太粗的步长会引入明显的数值误差。如果你追求快速验证PID参数可以先把模型降阶或者把最大步长放宽到0.005秒试跑如果曲线稳定再逐步细化。另外积分器初值一定要设置好。四旋翼模型初始状态通常设置为位置原点、欧拉角全零、速度为零。但如果你想仿真“从偏离位置收敛回原点”的场景就要把位置积分器的初值设置为偏离值否则阶跃试验做不了。这个设计在Simulink里很简单但经常被遗忘。4. 调参与结果分析的实战记录模型搭好了就到了最折磨人也最有趣的调参环节。我记录一下我当时实际调参的过程和数据你可以当作参考系来校准自己的模型。4.1 调参前的准备工作信号监视与Scope布局调参前我强烈建议你在模型中添加几个关键信号监视点位置误差x、y、z方向三个欧拉角及其期望值四个控制量输出四个电机的合成升力把这些信号接入Scope或Data Inspector放在同一个视图里观察。否则你只盯着一个位置曲线遇到问题很难判断是外环的问题还是内环的问题。我这里用的做法是在MATLAB里用to workspace把关键变量导出然后用一段脚本统一绘图。这样好处是每次仿真结束可以批量输出曲线对比图保存在本地方便回看和论文写对比分析。4.2 内环调参姿态响应从发散到平稳第一次跑模型我用姿态环PID初值(K_p5, K_i0.05, K_d1)。结果一运行roll角直接冲上60度然后剧烈振荡。这个现象非常典型P值太大导致系统不稳定。这时候我的处理方式不是继续调K_p而是把K_p降到1K_d保持1K_i设为0。跑一次观察系统是否稳定。结果响应虽然慢但能收敛说明基础结构没问题。然后把K_p逐渐加回来每加一次看一次振荡幅度直到找到临界值。这个过程快的话几轮就能完成。最终姿态环参数定格在(K_p2.8, K_i0.02, K_d1.6)超调量控制在5%以内调节时间大约2秒。这个指标对悬停控制够用了。这里有个经验调参数时不要同时动两个参数。每次只改一个观察曲线变化不然出了问题你都不知道是哪个参数引起的。这也是做控制调试最基本的实验素养但很多人急性子上来就把三个参数一起乱改结果彻底迷失。4.3 外环调参位置环调试的顺序逻辑位置环调试我建议先只调z轴高度环因为z轴只受升力影响与姿态解耦是最简单的一维系统。先把z轴高度环调稳定后再去调x、y方向因为x、y方向跟姿态耦合难度更高。高度环PID初始值我取(K_p0.8, K_i0.01, K_d0.8)。这个值基于模型质量和升力系数设了个初始估计。跑起来后发现z方向收敛速度还行但有明显稳态误差大概差了0.3米。加上积分项之后稳态误差被压到0.05米以内。这验证了一个规律光靠P和D的组合稳态误差压不干净必须有I来消除静差。x、y方向位置环的调试就痛苦一些。位置环的P输出给的是期望姿态角如果P太大内环收到的期望角度大幅跳跃姿态环响应不过来就会产生振荡。我的处理方式是限制位置环输出角度在正负15度以内让内环不至于太吃力。最终x、y方向位置环参数取(K_p0.5, K_i0.005, K_d0.6)响应曲线的收敛过程平滑无振荡。4.4 与论文结果的对比及指标验证调参完成后我把自己仿真得到的曲线与论文发表的曲线做对比。论文里给的是一个方形轨迹跟踪结果我的模型跑出来的轨迹跟踪效果在过渡段有少许超调稳态段精度良好。对比关键性能指标指标论文结果我的复现结果姿态角超调量约5%约4.2%高度稳态误差0.05m以内0.04m以内调节时间约2.5秒约2.2秒轨迹跟踪最大误差0.3m0.28m数据上略有差异是正常的因为软硬件环境、模型参数和控制器离散化方式不同。但趋势一致性说明复现成功。如果你复现出的曲线与论文曲线差异巨大先别怀疑PID参数先检查建模时是否用错了坐标系、力矩方向是否反了、升力系数是否标错这些基础性错误比参数错误更常见。5. 常见报错与排查方法四旋翼Simulink仿真基本是“改十次参数炸九次还有一次在炸的路上”我把常见报错和排查思路整理出来帮你少走弯路。5.1 仿真直接发散先查模型物理量纲最让人崩溃的是点击运行之后Scope里的曲线直接直线飞上去数值一下子变成无穷大或者NaN。这种时候几乎可以断定是物理模型或控制信号出问题了而不是PID参数问题。排查顺序建议是这样的检查每个信号单位是否一致。比如期望位置是米反馈位置是米如果一个是千米一个是米那PID输出就会畸变。检查控制量是否过大。四旋翼的最大升力是有上限的也就是十几牛的量级。如果你的升力输出动辄几十上百那肯定是中间换算出了问题。检查旋转矩阵有没有写错。这是很多人忽略的地方建议用一个单位阵前的特例去验证比如当欧拉角全为零时旋翼升力应该直接等于z方向的加速度不应该有横向分量。另外采样时间设置不合理也可能导致看起来像发散。比如控制器采样时间是0.1秒但动力学模型的积分步长是0.001秒控制器更新太慢也会引起发散。5.2 位置响应振荡越来越大多半是PID输出限幅没加有时候系统跑着跑着位置误差本来都要收紧了突然开始越来越大的振荡。这种情况常见于积分饱和但更多时候我发现是限幅不够。一开始我的位置环输出没有限幅期望角度直接给到姿态环。当位置误差还很大时位置环PID输出的期望角可能就是60度甚至90度这个角度远超四旋翼正常飞行范围姿态环根本拉不回来系统自然发散。解决办法是在位置环PID输出后加一个Saturation模块把角度限制在比如正负25度以内模拟真实飞控的倾斜角限制。5.3 稳态误差一直压不掉检查I项是否在起作用有朋友拿着仿真曲线来问说自己的高度稳定后一直有0.5米的误差怎么调都消不掉。我让他检查I项增益发现他设置的是0.0001数值太小积分器的累积速度远远赶不上误差的累积速度等于没加积分。把I项调到0.01之后再跑稳态误差很快就被压下来了。这里可以注意一个规律判断I项有没有起作用观察稳态阶段的控制量输出是否在持续缓慢变化。如果PID输出在稳态阶段纹丝不动说明积分项没有累积起来往往是增益太小或者PID模块的积分器被限幅限制了。5.4 同一套参数换个仿真时长结果差很多求解器步长在捣鬼有一次我把仿真时长从30秒改到120秒之后原本稳定的曲线在90秒左右突然开始振荡。排查了很久才发现问题不在控制参数而是在变步长求解器的最大步长设置上。仿真时间拉长后部分时间段求解器自动加大了步长导致数值精度下降系统在高频段出现了虚假振荡。这个问题的解决办法很粗暴把最大步长固定到0.001秒或者改用固定步长求解器。代价是仿真速度变慢但稳。对四旋翼这种非线性刚体系统来说仿真精度永远优先于速度。5.5 常见问题速查表现象可能原因排查手段运行报错“Input data must be real”某个中间变量出现复数检查是否有分母为负导致的根号运算曲线发散PID增益过大或模型单位错误减小P值验证系统是否稳定高频振荡D项过大或求解器步长过大减小D值或加密求解器步长稳态误差无法消除I项过小或积分被限幅增大I值检查积分限幅设置响应迟缓P过小或内环带宽不够增大P值检查姿态环是否已调好仿真速度极慢步长设置太小或模型非线性项过多去掉非关键非线性项放宽步长6. 复现之后还能做什么如果你已经成功复现了论文里的PID控制并且曲线和论文趋势一致那么恭喜你四旋翼控制最基础也最关键的闭环你已经跑通了。这时候很多人会问接下来呢我的建议是不要把复现当成终点。期刊论文复现最大的价值是你获得了“验证想法的实验平台”。比如你可以把PID改成模糊PID把外环换成模型预测控制或者加入风扰模型测试抗干扰能力每一步改进都能用现成的Simulink模型做对比验证这才是复现的延展价值。另一个值得做的事是把Simulink模型里的控制算法用代码重新实现一遍移植到嵌入式飞控平台。这部分涉及传感器模型、状态估计和控制频率匹配等问题超出了仿真的范畴但你的Simulink模型可以作为功能参照对比代码实现的控制效果这是行业里很常见的开发路径。最后给正在做这个方向的朋友一个提醒 四旋翼PID控制看着简单但它牵扯到坐标系变换、多环耦合、数值仿真精度和物理约束处理每一个环节都值得认真对待。不要被“复现失败”打击我身边几乎所有做过这个课题的人都经历过模型发散、参数爆炸的阶段。你把那些坑都踩过一遍并且能清楚地讲出每个问题背后的原理你就已经比大多数只“看论文”的人深入太多了。这篇文章里记录的模型代码思路、调参数据、报错排查方法都是可以复用的。如果你按照这个流程走了一遍大概率能跑出和论文对得上的结果。如果跑不出来欢迎回去检查每一步有没有遗漏尤其是坐标变换和限幅设置这两个环节这是复现四旋翼控制最常翻车的地方。