资讯动态

基于PD控制器的四旋翼无人机Matlab仿真与参数整定

发布时间:2026/10/24 4:37:54 来源:尧图企业网站定制
做四旋翼仿真控制我一直觉得最劝退新手的不是飞行器本身而是“模型还没建明白就先被各种高级算法淹没”。什么自适应、滑模、LQR听上去很酷但真正一跑仿真要么参数完全无从下手要么程序直接发散到NaN。我个人的建议始终是先老老实实把PID这一类线性控制器在Matlab里跑通尤其是PD控制器四旋翼的姿态控制核心就是它。这个项目“基于PD控制器的四旋翼无人机研究Matlab代码实现”要解决的正是从运动学建模、动力学仿真到双环PD控制落地的完整链路适合刚接触无人机控制、或者在写论文需要一套可复现基线方案的读者。这篇文章我按实际做项目的顺序来拆先讲清楚为什么PD控制器在四旋翼上有不可替代的位置然后给出可运行的建模与仿真代码再手把手讲参数整定和波形分析最后把我在仿真里踩过的坑整理成排查清单。全程都能直接照着抄。1. 四旋翼控制问题拆解为什么PD控制器是主流入门方案1.1 四旋翼的固有特性不稳定、欠驱动、强耦合四旋翼在空中是一个典型的开环不稳定系统。你把它放在空中松手它不会像固定翼那样靠气动自稳定而是会在几秒内直接翻过去。原因在于四旋翼本身没有自稳力矩它的力矩完全由四个电机转速差产生一旦没有反馈控制任何初始扰动都会被动力学放大。其次是欠驱动。四旋翼有六个自由度三个平动、三个转动但实际只有四个控制输入总拉力、滚转力矩、俯仰力矩、偏航力矩。这意味着你没法独立控制所有状态必须通过姿态的倾斜来产生水平方向的加速度。比如你想让无人机往北飞不是直接给一个向北的力而是先让机身俯仰倾斜让总拉力的水平分量产生向北的加速度。强耦合体现在两个层面一是滚转、俯仰、偏航力矩之间存在交叉项也就是陀螺力矩和转动惯量耦合二是位置和姿态强耦合位置变化依赖姿态角的变化。这种特性决定了控制结构必须是分层的外环管位置、内环管姿态内外环通过期望姿态角衔接。1.2 PD控制器为何能打天下PD控制器也就是比例-微分控制是四旋翼姿态控制里最经典、最实用的方案之一。它的控制律非常朴素u Kp * e(t) Kd * de(t)/dt其中e是期望值与实际值的误差Kp和Kd分别是比例和微分增益。比例项做“现在”的校正误差越大输出越大微分项做“未来”的预测误差变化越快输出的阻尼越强。在四旋翼场景里PD控制器有两个天然优势。第一四旋翼的角速度动力学相对干净在小角度假设下姿态角加速度与力矩输入近似线性关系PD控制器可以直接作用于角速度回路。第二四旋翼控制周期短通常1kHz到500Hz微分项在数字实现时不容易产生严重的相位延迟问题只要做好滤波PD在实物上也能稳定工作。很多人会问为什么不用PI或者PID积分项在姿态环里不是必需的。四旋翼悬停时重力力矩基本恒定PD控制的稳态误差可以通过前馈补偿或者机体配平来处理而在位置环里积分项可以消除风扰和重心偏移带来的静差但积分饱和又是另一套麻烦。所以先上PD跑通系统再视情况升级是最合理的技术路线。1.3 P、D参数的物理直觉整定PD参数关键要建立物理直觉而不是死记公式。Kp决定恢复力的大小。你可以把它想象成一根弹簧Kp越大弹簧越硬姿态角被拉回期望值的趋势越强。但Kp过大的直接后果就是系统振荡好比硬弹簧拉过头了会在期望位置附近来回摆。Kd决定阻尼的大小。你可以把它想象成活塞在黏稠液体里运动Kd越大运动的阻力越大振荡衰减越快。但Kd过大会让系统“发僵”反应迟钝甚至在离散实现中放大噪声。在二阶系统中闭环特征方程可以写成s^2 Kd*s Kp 0阻尼比ζ Kd / (2√Kp)。当ζ小于1时系统欠阻尼阶跃响应会超调ζ大于1时过阻尼响应慢但稳定。工程上四旋翼姿态环一般取ζ在0.8到1.2之间临界阻尼附近既快又稳。2. 四旋翼Matlab建模实操先把被控对象搞清楚2.1 坐标系与状态量约定建模第一步是约定坐标系这里最容易被忽略但最致命。惯性系E固定在地面z轴向上机体系B固连在机身上原点在质心x轴指向机头方向。无人机姿态用欧拉角表示滚转角φ绕x轴俯仰角θ绕y轴偏航角ψ绕z轴。状态量我用12维向量x [x, y, z, φ, θ, ψ, dx, dy, dz, p, q, r]^T其中前三个是惯性系下的位置接着三个是欧拉角再接着三个是线速度最后三个是机体角速度p、q、r。这里有个常见坑欧拉角在θ接近±90°时会有万向锁问题姿态解算会出现奇异。做悬停和小角度机动仿真通常没问题但如果做大机动就要考虑用四元数了。仿真入门阶段小角度假设够用但心里要清楚这个边界。2.2 动力学方程的简化推导四旋翼动力学可以拆成两部分平动和转动。平动部分牛顿第二定律在惯性系下成立m * d²r/dt² -mg * e_z R * F_b其中F_b是机体坐标系下的合力主要就是总推力T沿机体z轴方向R是从机体系到惯性系的旋转矩阵。注意重力在惯性系下恒指向下而推力方向随姿态变化。转动部分在机体坐标系下使用欧拉方程I * ω_dot ω × (I * ω) M其中I是转动惯量矩阵M是合力矩由电机转速差产生。对于对称的四旋翼非对角线转动惯量忽略后这个方程可以展开为三个通道的角加速度表达式。完整推导写出来很长但核心概念是角加速度等于控制力矩减去陀螺耦合项再除以转动惯量。2.3 状态空间与控制输入的关系四旋翼的四个控制输入通常定义为u1 T总拉力控制高度u2 Mφ滚转力矩控制滚转角u3 Mθ俯仰力矩控制俯仰角u4 Mψ偏航力矩控制偏航角在仿真中可以直接把u1到u4作为电机转速的合成结果但更接近实物的做法是先由PD控制器输出期望的力和力矩再通过混控矩阵解算四个电机的转速。Matlab仿真里通常在控制律层面直接用u1到u4电机混控放在另一个模块单独验证。简化建模时可以做一些合理假设机体为刚体、质量分布对称、电机响应足够快、空气阻力忽略不计。做初步研究时这些假设没有问题但写论文时最好说明假设条件与适用范围。3. 基于PD控制器的双环控制结构与代码实现3.1 外环位置控制、内环姿态控制的设计思路双环控制的总体思路是外环慢、内环快。位置环的带宽要比姿态环低3到5倍否则内外环会互相激励系统很容易振荡。位置环的工作方式如下给定期望位置(x_ref, y_ref, z_ref)位置PD控制器计算期望加速度。以z通道为例az_des Kpz * (z_ref - z) Kdz * (0 - dz)然后通过z通道期望加速度反算期望总拉力和期望姿态角。水平通道同理期望加速度ax_des、ay_des经过旋转矩阵逆变换得到期望的滚转角φ_ref和俯仰角θ_ref。偏航角一般单独给定。姿态环接收外环下发的期望姿态角通过姿态PD控制器计算期望角速度再由角速度内环通常也是P或PD计算控制力矩。最终输出u2、u3、u4。在Matlab里实现这个结构最直观的方式就是一个for循环跑完整个仿真时间每个时间步依次计算位置环、姿态环、动力学更新。3.2 双环PD控制仿真主循环代码解析% 四旋翼PD控制器双环仿真主循环 % 状态向量x [x y z phi theta psi dx dy dz p q r] clear; clc; close all; % 物理参数 m 1.2; % 质量 kg g 9.81; % 重力加速度 Ixx 0.02; Iyy 0.02; Izz 0.04; % PD参数 Kp_z 2.0; Kd_z 2.4; % 高度通道 Kp_phi 2.5; Kd_phi 1.6; % 滚转通道 Kp_theta 2.5; Kd_theta 1.6; % 俯仰通道 Kp_psi 1.5; Kd_psi 0.8; % 偏航通道 % 仿真设置 dt 0.005; % 控制周期 200Hz t_end 10; % 仿真时长 10s time 0:dt:t_end; n length(time); % 初始状态悬停在10m高度水平姿态 x zeros(12,1); x(3) 10; % 记录历史数据 history zeros(n, 12); history(1, :) x; % 期望轨迹 z_ref 5; % 期望高度 psi_ref 0; for k 1:n-1 % 当前状态 z x(3); dz x(9); phi x(4); theta x(5); psi x(6); p x(10); q x(11); r x(12); % 外环位置控制 az Kp_z * (z_ref - z) Kd_z * (0 - dz); T m * (g az); % 总拉力补偿重力 % 水平位置保持假设期望位置为原点 ax -0.5 * x(1) - 1.0 * x(7); ay -0.5 * x(2) - 1.0 * x(8); % 由水平加速度反算期望姿态角小角度近似 theta_ref (ax * cos(psi) ay * sin(psi)) / g; phi_ref (ax * sin(psi) - ay * cos(psi)) / g; % 内环姿态控制 u_phi Kp_phi * (phi_ref - phi) Kd_phi * (0 - p); u_theta Kp_theta * (theta_ref - theta) Kd_theta * (0 - q); u_psi Kp_psi * (psi_ref - psi) Kd_psi * (0 - r); % 控制量分配简化模型 u1 T; u2 u_phi; u3 u_theta; u4 u_psi; % 动力学更新简化 % 线加速度 ddx (u1/m) * (cos(phi)*sin(theta)*cos(psi) sin(phi)*sin(psi)); ddy (u1/m) * (cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi)); ddz (u1/m) * cos(phi)*cos(theta) - g; % 角加速度忽略陀螺耦合项小角度假设 dp u2 / Ixx; dq u3 / Iyy; dr u4 / Izz; % 状态更新欧拉积分 x(1) x(1) x(7)*dt; x(2) x(2) x(8)*dt; x(3) x(3) x(9)*dt; x(4) x(4) p*dt; x(5) x(5) q*dt; x(6) x(6) r*dt; x(7) x(7) ddx*dt; x(8) x(8) ddy*dt; x(9) x(9) ddz*dt; x(10) x(10) dp*dt; x(11) x(11) dq*dt; x(12) x(12) dr*dt; % 记录 history(k1, :) x; end % 绘图 figure(1); subplot(2,1,1); plot(time, history(:,3), LineWidth, 1.5); hold on; yline(z_ref, r--, LineWidth, 1.2); grid on; xlabel(时间/s); ylabel(高度/m); legend(实际高度,期望高度); title(高度通道阶跃响应);这段代码是我在实际项目里经常用的“骨架版”核心逻辑完整可以直接复制跑通。注意我用了欧拉积分仿真步长0.005秒时稳定性没有问题如果步长加大到0.02秒以上建议换成四阶龙格库塔避免数值发散。3.3 姿态动力学函数与完整代码规范上面主循环里我省略了陀螺耦合项为了更接近真实模型这里给出一个更完整的姿态动力学函数。注意转动物理学必须用机体坐标系下的角速度p、q、r来计算欧拉角速率不等于机体角速度需要经过变换矩阵。function dx quadrotor_dynamics(t, x, I, g, m) % x: [phi theta psi p q r]^T Ixx I(1); Iyy I(2); Izz I(3); phi x(1); theta x(2); psi x(3); p x(4); q x(5); r x(6); % 欧拉角速率与机体角速度关系小角度近似 phi_dot p sin(phi)*tan(theta)*q cos(phi)*tan(theta)*r; theta_dot cos(phi)*q - sin(phi)*r; psi_dot (sin(phi)/cos(theta))*q (cos(phi)/cos(theta))*r; % 欧拉方程含陀螺耦合项 p_dot (Iyy-Izz)/Ixx * q*r; q_dot (Izz-Ixx)/Iyy * p*r; r_dot (Ixx-Iyy)/Izz * p*q; dx [phi_dot; theta_dot; psi_dot; p_dot; q_dot; r_dot]; end把这段函数与主循环对接时你需要在主循环里通过控制量u2、u3、u4把p_dot、q_dot、r_dot的计算补上加上控制力矩项。我个人推荐用Matlab的ode45来跑这种连续动力学比手写欧拉积分精度高很多尤其当你想验证控制器在大扰动下的表现时。4. 参数整定过程与仿真结果分析4.1 手动整定顺序与初值选取四旋翼PD参数手动整定有一个铁律从内到外先姿态后位置先P后D。不要一上来就去调位置环位置环动起来之前姿态环必须已经稳定。我的整定步骤是这样第一步固定偏航通道设定较小的Kp_psi和Kd_psi让偏航先稳住。第二步调俯仰和滚转通道。先只给Kp从0.5开始每次增加0.5观察姿态角的阶跃响应。当出现等幅振荡时记录当前Kp作为临界增益然后往回退到临界增益的40%到60%这是Kp的基准值。第三步在Kp基准值基础上加Kd。Kd从0开始每次增加0.2观察超调量和振荡次数。合适的Kd会让超调明显减小、振荡在2到3个周期内衰减完毕。继续增大Kd直到响应开始变慢或者出现高频抖动说明Kd过量了回退20%。第四步姿态环稳定后再整定位置环。位置环的整定同样先P后D但注意位置环Kp不能太大否则位置误差会转换成过大的姿态角指令导致姿态环饱和。这里给出一个我自己常用的初始参数参考表控制通道Kp初始值Kd初始值调节步长高度z1.00.80.2滚转φ2.01.20.5俯仰θ2.01.20.5偏航ψ1.50.80.3水平位置x/y0.50.80.14.2 如何解读仿真结果曲线仿真跑完以后不要只看最终波形“好像稳定了”专业做法是提取关键指标。以高度通道阶跃响应为例我要看四组数据超调量。期望高度5米响应曲线最高冲到5.6米超调量就是12%。姿态环超调量控制在10%以内是合格标准超过20%说明Kp偏大需要降低Kp或者加大Kd。调节时间。定义响应进入期望值±2%误差带并保持不再超出的时间。姿态通道参考标准是1秒以内位置通道可以放宽到2秒以内。稳态误差。期望5米最终稳定在4.95米稳态误差就是1%。PD控制器在纯重力环境下如果前馈补偿做得准稳态误差应该很小。振荡次数。整个响应过程中穿越期望值的次数理想情况是1到2次。大于4次说明阻尼不足。仿真里还有一个重要技巧先单独测试姿态环给定固定参考角观察闭环响应再接通位置环观察整个级联系统的响应。如果级联后出现新的振荡大概率是内外环带宽太接近我一般会把外环增益降低30%到50%再试。4.3 整定过程中的常见参数误区我见过很多新手把Kp调得极大以为“越大响应越快”。结果响应确实快了但代价是系统变成高频振荡器。有一次我做个模拟项目姿态环Kp给到8Kd给了3滚转角响应当真干脆0.1秒就到目标角但角速度曲线上全是±50度每秒的锯齿形抖动。这就是典型的P过大、D不足以压制超调。另一个误区是盲目套公式。网上有文献说二阶系统整定公式Kp ωn²Kd 2ζωn然后ωn取10算出来Kp100、Kd20直接放上去仿真发散。原因在于动力学模型存在延迟环节和耦合项理论公式的假设条件不满足。正确做法是用公式确定量级再用仿真细调。第三个误区是忽略仿真步长。PD控制器本质上是离散控制当仿真步长设置太大时微分项的差分近似误差会放大。我在一个仿真里用0.05秒步长同样的参数跑出完全发散的结果改成0.01秒后系统稳定得非常好。如果你的参数在别人代码里稳定、在自己代码里发散优先检查步长和离散化方式。5. 常见问题与排查技巧实录5.1 仿真发散到NaN的处理思路Matlab仿真中最常见的问题就是跑到某一步状态量变成Inf或者NaN。我遇到过三种情况。第一种是角度单位搞混。Control库和飞行器模型库一个用度、一个用弧度PD输出的控制量瞬间爆炸姿态角就飞了。排查方法是写一个单位断言每步检查|phi|是否大于π/2一旦超过就报错。这个检查看起来笨但救了我好几次。第二种是旋转矩阵计算错误。比如把欧拉角的旋转顺序搞错导致推力方向计算不对整个系统变成一个正反馈。这种错误很难直接从波形判断我的排查方式是用一组已知状态手工算一遍旋转矩阵再用数值方法验证。第三种是数值积分不稳定。欧拉积分方法对步长非常敏感当步长与系统最小时间常数不匹配时会出现数值振荡。解决方式是把ode45的误差容差调小或者改用ode113这类变步长积分器。5.2 响应振荡或过慢时的定向调节技巧这里我总结了一套实用的定向调节口诀全是经验之谈如果响应超调大、振荡剧烈优先增加Kd而不是降低Kp。很多时候Kp保持不动Kd翻倍振荡就压住了。如果响应缓慢、上升时间长说明Kp不够或者Kd太大了。先用阶跃测试确认是不是Kd把系统压得太“僵”。如果系统出现持续高频抖动大概率是微分项在放大噪声。检查仿真里是否加入了传感器噪声如果有给微分项加低通滤波截止频率一般取控制频率的1/5。如果系统有稳态误差且不消除这是PD控制器的固有问题。仿真中检查是否漏了重力前馈我之前用过一段代码高度控制没加前馈悬停误差一直有0.3米加了一行前馈补偿后误差降到0.02米以内。5.3 从仿真向实物移植的关键差异仿真跑通了迁移到实物前一定要意识到仿真里没有时延和噪声实物里有。即使你用Matlab做过再细致的仿真也替代不了实物调试。这里有三个必须做的前置工作。第一个是控制频率与传感器频率的匹配。常见飞控的姿态解算频率是1kHz但如果你的控制频率只有200Hz微分项的计算需要额外注意。第二个是电机饱和。仿真里PD输出无限大都没关系但实物电机转速有上限控制量达到饱和区后系统响应会明显变差。仿真里务必加饱和限幅模块并且在整定参数时要留出20%的电机余量。第三个是控制量符号约定。这个坑最隐蔽不同坐标系定义下同样的正力矩产生的角加速度方向可能完全相反。仿真阶段用同一套坐标系一般不会出问题但移植到实物飞控时必须对比实物固件的模型约定否则就会出现“给正力矩飞机反而越偏越远”的诡异现象。从仿真的PD到实物上的串级PID中间还会经历滤波器整定、遥控器混控、姿态估计融合等环节但那已经进入飞控开发的下一阶段了。至少在这篇里把PD在Matlab里跑通、把参数整定逻辑搞清楚已经能覆盖大多数课程设计和论文仿真需求。我个人在多次反复调参中最大的体会是PD控制器的性能上限取决于你对被控对象特性的理解程度。公式和代码都是现成的真正值钱的是调整参数时那些“为什么会这样”的判断——为什么Kd过大会抖为什么外环带宽必须低于内环为什么仿真步长会影响稳定性。把这些底层逻辑想明白你再去看任何更高级的控制器都不会觉得晕。最后再分享一个小技巧仿真代码里加一段自动保存参数和对应曲线的功能每次调参都留下记录。这样当你做了几十次试验、最终找到一组好参数时还能回溯清楚是逐步怎么调出来的而不是靠最后那次碰运气。这个习惯能让你在写论文和做实物移植时省掉大量重复劳动。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑