☰
四旋翼无人机PID轨迹跟踪控制仿真:从建模到调参全解析
2026/10/20 9:17:30 网站建设 项目流程

做飞行控制方向的人,大概都有过这种经历:论文里那些漂亮的轨迹跟踪曲线,自己动手在Simulink里复现时,不是发散就是震荡。最近我把一个基于PID的四旋翼无人机轨迹跟踪控制仿真程序完整整理了一遍,从四旋翼动力学建模、PID控制器设计到圆形轨迹的闭环跟踪验证,全在MATLAB Simulink环境下跑通,过程中踩了不少坑,也总结出一套从模型搭建到参数整定的通用流程。这篇文章就把这套仿真程序的思路、模型细节、控制器结构以及调参时容易忽略的问题完整拆一遍,适合正在做飞控入门、课程设计或者想快速验证控制算法的同行参考。


1. 轨迹跟踪任务拆解:先想清楚要控什么

1.1 欠驱动系统的本质

四旋翼是一个典型的欠驱动系统:它拥有6个自由度,但能直接控制的只有4个输入——四个电机的转速。这意味着你不能像控制一个全驱动机械臂那样,直接对位置和姿态的6个方向都施加独立控制力。水平方向的位置移动,本质上靠的是把机体倾斜后,总推力在水平面上产生的分量。这个特性决定了轨迹跟踪必须采用“内外环”结构,而不是简单地做6个独立PID。我在仿真程序里把这个关系放在第一位,建模时也不断提醒自己:水平加速度不是直接控制量,它是滚转角、俯仰角和总推力的间接结果。

有了“倾斜产生水平加速度”这个基本认知,整个控制器设计就有了主线:外环位置控制器根据轨迹误差计算需要的期望加速度,再把期望加速度换算成机体期望姿态角;内环姿态控制器负责快速响应这些期望角度并输出力矩。两条回路串在一起,就构成了完整的轨迹跟踪闭环。很多初学仿真时容易把注意力放在PID公式本身,但系统结构如果没搭对,后面调多少组参数都救不回来。

1.2 外环位置与内环姿态的串级结构

串级结构的好处是责任清晰。外环只管“位置偏离了多少、需要怎样的加速度补偿”,它不关心电机怎么转;内环只管“姿态角偏差多少、需要多大力矩把姿态扳回来”,它也不太在意无人机正往哪儿飞。职责分离之后,调参就可以分层进行:先把内环姿态环调稳,再去碰外环位置环,一旦出现问题也知道该去查哪一层。

我在仿真里设的内环带宽明显高于外环。位置控制器的输出周期可以放慢到20ms甚至50ms,姿态控制器则要求10ms以内做出反应。这个时间尺度的分离不是拍脑袋定的,而是从控制工程里的“时间尺度分离”原则来的:如果外环动作频率接近甚至超过内环的执行能力,内环还没完成姿态调整,外环又叠加了新的指令,整个系统就会进入相互干扰的振荡状态。实际调参经验是位置环带宽大约取姿态环带宽的三分之一到五分之一比较稳。

1.3 为什么入门方案选PID而非高阶算法

这个仿真程序选用PID,不是因为它“高级”,恰恰是因为它足够朴素且有效。对比LQR、MPC、滑模这些算法,PID最大的优势是模型依赖弱、物理含义清楚。它只需要知道偏差、偏差积分、偏差变化率,就可以把控制器搭建起来。对于刚接触四旋翼控制的人来说,PID可以把注意力集中在对象本身:先理解被控模型、信号连接、单位换算、正负反馈这些基本功,而不是一上来就被权重矩阵或者预测时域拖住。

当然,PID不是万能药,它无法显式处理输入约束和最优性问题。但作为一套轨迹跟踪仿真程序,PID先把整个闭环打通,之后要升级成LQR或者MPC,控制器模块直接替换即可,被控对象模型和轨迹生成器完全不用动。这也是我推荐先做PID版本的原因——它就像一个最小可靠骨架,后续所有高级玩法的骨架基础都在里面。


2. 建模与坐标约定:仿真不发散的第一道保险

2.1 坐标体系与欧拉角顺序

四旋翼建模必须先统一坐标体系。我使用的地面坐标系采用北东地NED约定,机体坐标系固定于无人机重心:X轴指向机头方向,Y轴指向右翼,Z轴向下。这里要特别留意推力方向:四旋翼的螺旋桨产生的推力始终沿机体Z轴负方向,也就是“向上”。如果建模时把推力方向搞反,仿真会像失控一样直接砸向地面。

欧拉角旋转顺序我选了ZYX顺序,也就是先偏航、再俯仰、最后滚转。这个顺序在航空领域最常用,后面的姿态角换算公式都建立在这个约定之上。仿真程序里所有角度量默认都用弧度,所有角速度都用弧度每秒,速度用米每秒,力和力矩分别用牛顿和牛米。这些单位看起来很基础,但我见过太多仿真数据数量级不对,最后发现是把角度用了度、角加速度积分出来变成弧度每秒、控制输出直接差了57倍。单位统一是“不发散的第一道保险”,这句话一点都不夸张。

2.2 刚体动力学与电机模型

四旋翼的动力学方程从刚体运动学出发。平动方程可以写成质量乘加速度等于重力、总推力、空气阻力之和;转动方程则表达为惯性矩阵乘角加速度等于外力矩减去陀螺力矩耦合项。低速室内场景下,空气阻力可以先用一个简化的线性阻尼代替,电机响应特性和螺旋桨气动细节集中到推力模型中。

电机和螺旋桨的建模我建议用一阶惯性环节外加平方关系。螺旋桨转速从指令到实际变化不是瞬间完成的,而是存在一个一阶滞后,时间常数大约在0.05到0.3秒之间。推力与转速的平方成正比,力矩也与转速的平方成正比,且方向与转速方向相反。仿真程序里可以先用如下参数:机体质量1.5千克、机臂长度0.225米、转动惯量分别取Ixx=Iyy=0.02、Izz=0.04千克平方米,电机时间常数0.1秒。悬停转速可以用m g / (4 * kF)开平方估算,得到大约500弧度每秒,也就是接近4800转每分,这个数量级符合真实小型四旋翼的电机工作范围。

2.3 Simulink里的被控对象实现

被控对象模型有两种实现方式:一种是把动力学方程用Simulink中的加法器、积分器、乘积模块一个个搭出来,另一种是写成S-Function或者MATLAB Function模块,在代码里定义状态方程。我推荐用后者。原因很简单,动力学方程包含几十条线路信号,用图形化模块搭建虽然直观,但一旦要调整模型细节,比如加一个气动阻尼项、改一个惯性数值,图形上改线比改代码更容易出错。把模型封装成函数后,输入是四个电机控制指令,输出是位置、速度、欧拉角、角速度,整个被控对象变成一个标准的模块,控制器连接非常干净。

我在Simulink里用了一个Level-2 MATLAB S-Function封装六自由度模型,状态量取12个:地面系下的三维位置、三维速度、机体系的角速度,加上用欧拉角表示的姿态。姿态运动学用欧拉角微分方程实现,没有用四元数,因为轨迹跟踪场景基本不涉及大幅机动,欧拉角表达足够直观,也方便观察姿态变化曲线。如果后续要扩展到特技飞行或者全姿态控制,建议再切换到四元数避免万向锁问题。


3. PID控制器设计与Simulink搭建细节

3.1 控制律结构与方程

整个控制律分为位置控制律和姿态控制律两层。位置层我采用的是带前馈的PD控制加轻度积分:期望加速度等于轨迹生成器给出的参考加速度,加上位置误差的比例项、速度误差的微分项,以及小增益的积分项来消除静差。积分增益控制得很小,主要是为了避免期望加速度指令长期饱和。垂直方向上,高度控制增加了一个悬停油门前馈项,因为四旋翼需要持续输出与重力平衡的推力,如果只靠积分慢慢磨出这个基准油门,高度响应会很迟钝。

姿态层参考常见的角度环加角速度阻尼结构:滚转和俯仰通道用期望角度的比例误差项,配合角速度的阻尼项来抑制振荡,偏航通道独立控制,因为偏航运动不影响水平推力方向。姿态控制输出的是机体轴三个方向的力矩指令,这个力矩最终换算成四个电机的转速分配。分配的映射关系我在Simulink里用了一个增益矩阵实现,本质上是把总推力、滚转力矩、俯仰力矩、偏航力矩线性组合成四个电机指令,这个矩阵在模型搭建时定义一次,后续不用改动。

3.2 从期望加速度到期望姿态角的换算

这一节是整个控制器里最容易出错的地方,也是最值得展开的。位置控制器输出的期望加速度有三个分量:水平面的期望加速度和垂直方向的期望加速度。期望滚转角由期望水平加速度、期望偏航角以及重力加速度组合得到,期望俯仰角同理,但符号与滚转角相反。垂直通道则直接把期望垂直加速度加上重力,再除以滚转俯仰角余弦的乘积,换算成期望总推力。

公式推导时做了一个小角度近似,假设cos滚转角和cos俯仰角都接近1,这在常规轨迹跟踪里完全够用。我做仿真时特意在轨迹生成器里加了最大加速度限制,避免控制器期望角度超过四旋翼能实现的物理范围。比如说圆形轨迹半径5米、巡航速度2米每秒,需要的向心加速度是0.8米每平方秒,对应的期望倾角只有约4.7度,完全在近似条件下。如果未来做高速急转弯,需要去掉小角度假设,直接用完整公式计算期望姿态角。

3.3 Simulink子系统划分与信号流

我习惯把仿真程序分成五个子系统:轨迹生成器、位置控制器、姿态控制器、被控对象模型、数据记录模块。信号从轨迹生成器出发,输出参考位置、参考速度、参考加速度、参考偏航角,进入位置控制器;位置控制器输出期望滚转、俯仰角以及期望总推力;姿态控制器基于当前姿态和角速度,输出三轴力矩;力矩和总推力一起进入被控对象模型,计算出新的状态量;状态量再反馈回位置控制器、姿态控制器和数据记录模块。

子系统之间全部使用Bus信号连接,好处是可以把很多路线打包成一条总线,Simulink模型看起来非常清爽,排查问题的时候也能直接看总线的某个成员信号。我在被控对象模型输入端用了一个Demux模块把推力力矩向量拆开,保证控制器输出维度与模型输入维度严格一致。这里要提醒一下:Simulink对信号维度非常敏感,如果模型期望的是四维电机指令,你输入的却是三维力矩向量,直接会在仿真开始时报维度错误,这种问题排查起来最快。

3.4 轨迹生成与常用指令

轨迹生成器在仿真里扮演的是“任务下发”的角色。我做了三种模式方便测试:阶跃给定、圆形轨迹、八字形轨迹。阶跃模式用来做控制器整定,通过观察位置和姿态的阶跃响应曲线,可以直观看到超调、振荡和稳态误差;圆形轨迹用来验证连续跟踪能力,半径取5米,角速度取0.4弧度每秒,对应的线速度约2米每秒;八字形轨迹用参数方程实现,可以检验无人机在变速变向时的动态品质。

轨迹生成器输出的参考加速度对跟踪精度影响很大。如果前面说的位置控制器采用比例加微分,在没有前馈的情况下,跟踪圆形轨迹总会存在一个相位滞后,导致实际轨迹直径比给定轨迹小一圈。加入参考加速度前馈之后,控制器预判了轨迹弯曲所需的向心加速度,跟踪误差会明显下降。这个改进非常直观,也是判断一个轨迹跟踪程序是否专业的关键细节。

3.5 仿真求解器与采样时间设置

求解器配置看起来是不起眼的环节,但对仿真结果的真实性影响很大。我在大多数场景下使用变步长求解器并启用零交叉检测,最大步长设置为0.01秒,仿真时长30秒。PID控制器部分如果用连续模块直接计算,那么控制律在步长之间会被求解器自动插值;如果要模拟真实飞控的离散控制逻辑,可以在控制器输入输出端添加零阶保持器,并统一设置采样时间为0.01秒。

采样时间的选择有一点需要说透:位置控制环我单独用了一个10毫秒采样周期,姿态控制环与它相同也可以,但很多实际飞控会把姿态环跑得更快,比如5毫秒甚至2.5毫秒。如果仿真程序里想体现这种差异,就把内外环的零阶保持器分别设置成不同采样时间。这里要注意连续模型和离散模型混用时的仿真行为,当离散控制器采样时间与最大步长不匹配时,会出现台阶状响应,这是正常的,但不要误认为是模型振荡。


4. 调参流程与从“能飞”到“飞得好”的进阶细节

4.1 内外环带宽分离原则

调参之前再强调一次带宽分离原则。姿态环必须比位置环快,这是串级PID能够稳定的前提。我在仿真里先单独给姿态环一个阶跃信号,观察滚转角响应曲线,调整姿态增益直到响应快速且没有明显超调;再去调位置环。如果姿态环没稳定就去调位置环,你会看到不管怎么调节位置参数,整个系统都像一坨浆糊,因为内环的响应滞后已经破坏了外环的控制相位裕度。

量化来看,我先把姿态环响应带宽调到约8到10弧度每秒,响应时间大约0.1到0.2秒,再把位置环带宽设计在2到3弧度每秒,响应时间约0.5秒。这个比例保证了位置环不会指望姿态环“瞬间”完成动作,而是留给内环充足响应时间。很多调参教程不讲这一点,直接丢一组PID参数,实际上参数背后的带宽关系才是串级PID的灵魂。

4.2 用临界比例度法给PID设定初值

初始参数从哪里来?我推荐用工程上成熟的经验方法:先把积分和微分增益全部置零,只留比例增益,从小到大逐步增大,直到系统响应出现等幅振荡,记录此时的临界增益和临界振荡周期。然后按经典经验公式整定比例、积分、微分参数,再根据实际响应做微调。这个方法对姿态环很见效,对位置环需要先关闭前馈再做,因为前馈会掩盖反馈参数的不足。

实际跑仿真的过程中,我用这个方法获得的初始参数大概在一开始控制姿态角时使用比例增益约6、阻尼项约1的样子,之后微调的过程更像是“把系统调到临界点再退回半步”:增大比例到刚好出现轻微振荡,记录参数,然后取临界值的60%左右作为工作点。这里的经验是,让系统工作在一个“离振荡临界点还有一点余量”的位置,而不是一味追求快速响应。过大的比例增益必然会带来传感器噪声放大和电机饱和,这在仿真里也许看不出来,但到了实物上就会原形毕露。

4.3 积分饱和与微分噪声处理

PID上容易出问题的两个环节是积分饱和和微分噪声。轨迹跟踪仿真里,如果期望位置离初始位置很远,位置环的积分项可能在到达目标前就累积到一个很大的值,导致无人机越过目标点之后依然不能马上停下来,出现明显的超调和来回振荡。我的处理方式是对积分项本身加限幅,同时当控制输出触达力矩或加速度限制时,冻结积分累积,也就是采用条件积分方法。在Simulink里实现这个逻辑只需要一个饱和模块和一个使能开关。

微分噪声问题在姿态环上尤为突出。直接对姿态角信号求差分,会把信号中最细小的噪声放大成巨大的角速度毛刺,进而造成力矩指令高频抖动。我用的是角速度反馈来代替纯微分项,因为被控对象模型里本身就有角速度状态,直接测量它既物理上合理又免去了信号差分放大的问题。如果一定要在位置环做纯微分,建议先在位置信号后面加一个一阶低通滤波器,截止频率根据轨迹带宽选择,通常取5到10赫兹。

4.4 前馈补偿明显提升跟踪精度

当基础PID调试完毕、系统能够稳定悬停和跟踪直线之后,一定要加上前馈补偿再对比一下。前馈的核心思想很简单:控制器不仅要根据误差修正运动,还要根据期望轨迹本身的速度和加速度提前输出对应的控制量。位置环的期望加速度直接等于参考加速度加上误差修正量,姿态环的期望角速度可以加入参考偏航角速度项,这样跟踪高速圆形轨迹时姿态不会明显落后。

我在同样的圆形轨迹下做过对比:纯反馈控制时,跟踪误差大约有0.35米,听起来不大,但在5米半径的圆上看起来已经像是一个偏心的椭圆;加入前馈后,误差降到0.05米以内,曲线几乎重合。前馈项的加入也意味着调参顺序要做调整——先加前馈消除稳态滞后,再细调PD参数处理瞬态过程,否则两套机制混在一起会互相掩盖问题。


5. 常见问题与排查实录

5.1 一给阶跃就发散怎么办

仿真一启动就指数发散,十有八九是信号极性或者模型结构问题,不是PID参数问题。检查顺序是这样的:先看电机转速是否为正、推力方向是否沿机体Z轴负方向;再看期望姿态角换算公式的符号是否与旋转顺序匹配;最后把控制器增益全部调成很小的值,比如0.01,观察系统是否为开环稳定状态。如果开环状态下位置还在漂移,说明模型本身有问题,得回头查重力和推力方程,而不是继续调增益。

一个我踩过的典型坑:位置控制器输出的期望加速度单位是米每平方秒,但我在换算期望姿态角的子系统里忘了除以重力加速度,导致同样的位置误差对应了9.8倍过大的期望倾角,仿真结果自然是剧烈的倒立摆式摆动。这类问题只要在模型里添加信号标注,并且在Scope中同时观察期望姿态角和实际姿态角,就能一眼发现两者数量级不匹配。

5.2 悬停有稳态误差

无人机到达目标点后停在半空,但位置始终偏离目标十几厘米,这种稳态误差通常是积分作用不足或重力补偿不准造成的。垂直方向上的成因最典型:总推力指令里如果没有包含悬停油门前馈,积分项只能一点点地补上重力抵消的基准值,过程中会残留一个由积分时间决定的静差。我的处理方式是在垂直通道直接加入一个由质量和重力计算得到的悬停推力常数,让PID只需要处理扰动误差,而不是负责生成整个基准推力。

水平方向的稳态误差则要检查机体的初始偏航角是否与期望偏航角一致。如果轨迹生成器输出的期望偏航角是0,但被控对象初始偏航角是15度,位置控制器换算期望姿态角时会把一部分前向加速度分量映射到侧向通道,产生看似静差其实是姿态坐标旋转未校准的问题。

5.3 圆形轨迹跟踪明显滞后

圆形轨迹跟踪出来的曲线比给定轨迹小一圈,或者相位总是落后,典型原因有两个。一是位置环带宽不足,反馈修正速度跟不上弯曲轨迹的变化,解决方法是提高位置环比例增益,或者增加参考加速度前馈;二是姿态环响应太慢,期望姿态角还没跟上,水平推力分量已经滞后,这时要回头调姿态环参数。

我建议先在同一个图里同时绘制给定轨迹和实际轨迹,并用颜色区分误差大小,观察误差最大的位置是在圆周的哪个地方。如果误差集中在90度方向和270度方向附近,是明显的向心加速度前馈缺失;如果误差均匀分布在整圈且时大时小,大概率是环间带宽匹配问题。定位到问题来源后再动手,比盲目乱调参数高效得多。

5.4 姿态角高频抖动

姿态角曲线看起来在目标值附近高频震颤,幅度不大但频率很高,原因多半是微分项对噪声过度敏感,或者仿真步长太大导致控制器在每个积分步上的动作不一致。先检查姿态角信号来源,如果直接取了欧拉角的数值差分做微分项,几乎必然会出现高频毛刺。改用角速度状态作为姿态环的阻尼项是最直接的办法。

如果用的是变步长求解器,还需要检查最大步长设置。最大步长太大会导致姿态响应曲线上出现台阶状的小锯齿,看起来像抖动。把最大步长缩小到0.005秒甚至0.001秒,观察抖动是否消失,就可以区分是数值伪振荡还是控制律本身的问题。这一步排查在纯仿真阶段必须做,否则会把数值问题带进真实飞控的代码里,造成灾难性的调试成本。

5.5 调试顺序与版本管理

最后分享一个非常实际的工作习惯:我每次只改一个参数,并且把每次仿真结果的曲线截图和参数文件一起保存,文件名带版本号和时间。这样做初看有点繁琐,但调参进入中后期后价值巨大。否则你可能连续调了三组参数,却说不清哪组对应哪张曲线,最后只能从头再来。

调试顺序严格遵循“先内后外、先姿态后位置、先悬停后跟踪”的步骤:第一步是姿态环阶跃响应,第二步是高度环阶跃,第三步是水平位置阶跃,第四步是圆形轨迹跟踪,每一步没有达到预期指标前不进入下一步。这个流程看起来很保守,但它能保证每一层闭环在进入下一层之前都经过充分验证,最终的整体系统调试往往一次就能通过。


我个人在实际调试这套仿真程序中最深的体会是,四旋翼轨迹跟踪控制的难点从来不是PID公式本身——公式一节就能写完,真正的复杂度集中在模型坐标约定、信号维度、单位换算、反馈极性这些“不聪明但必须严谨”的地方。只要把底层逻辑理顺,PID参数往往一次就能调到不错的水平;反过来,底层有任何一个符号错误,调参过程会变成一场无尽的灾难。建议手头有仿真任务的同行,在动手之前先把坐标系、单位制和信号流画出来,再开Simulink拉模型,这个过程省下来的时间和精力,绝对比你想象的还要多。

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

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

立即咨询