飞机稳定性分析这块,平时课程作业或者课程设计里遇到最多的就是“用MATLAB算纵向和横向稳定性”这类题目。它看起来像是一个仿真作业,实际上是把飞行力学里的气动导数、状态空间方程、模态分析这些东西全部串起来。很多同学卡住的地方往往不是MATLAB本身,而是不知道怎么把物理模型变成代码能算的东西,算完之后又不知道怎么判断结论对不对。这篇东西就来把整套流程完整拆一遍,从建模原理到代码实现,再到怎么排查结果异常,尽量讲透。
飞机纵向和横向稳定性研究的MATLAB实现全流程
先说明白这篇博文要解决什么。输入是一个典型的“基于MATLAB飞机纵向和横向稳定性研究”项目,这类项目在航空航天专业的课程设计里非常常见,核心任务就三件事:建立飞机的纵向和横向小扰动运动方程,求出状态矩阵的特征值,判断飞机是否稳定,最后整理成报告。它解决的问题是,让一台飞机的气动参数摆在你面前时,你能用数值方法快速判断这架飞机是不是“天生稳定”,以及它在扰动下会表现出什么样的运动模态。
这套东西适合谁看?如果你是飞行器设计、飞行力学方向的本科生,或者在做无人机飞控开发需要初步判断飞行品质,再或者单纯是自学MATLAB想找点有含金量的练手项目,这篇都值得读下去。我会把里面最容易踩坑的地方——气动导数的正负号约定、单位统一、特征值如何对应物理模态——全部展开讲。
1. 稳定性研究到底在研究什么
1.1 纵向与横向的物理分界
飞机的运动可以拆成纵向和横向两组来看,这是飞行力学里的经典做法。纵向运动发生在飞机的对称平面内,涉及前后速度变化、迎角变化、俯仰角速度这些量,你可以把它想象成飞机在竖直平面里的“抬头低头”行为。横向运动则涉及侧滑、滚转和偏航,是飞机绕机体坐标轴的非对称运动,想象一下飞机在水平面里“侧身转向”的样子。
为什么要分开研究?因为在小扰动的前提下,这两组运动之间的耦合非常弱,可以近似解耦分析。纵向的扰动不会立刻激起明显的横向响应,反之亦然。这就像家里装修时把电路分成照明和插座两组,虽然都由总闸控制,但检修时可以分开处理。
1.2 静稳定性与动稳定性:两个层次的判断
稳定性本身分两个层次:静稳定性和动稳定性。
静稳定性判断的是“趋势”。当飞机因扰动偏离配平状态时,气动力会形成让飞机回到原位的趋势吗?对纵向来说,看俯仰力矩对迎角的导数 \(C_{m\alpha}\) 是不是负数——如果是负的,迎角增大会产生低头力矩,把飞机拉回去。横向静稳定性则看 \(C_{l\beta}\) 和 \(C_{n\beta}\) 的符号,分别对应滚转和偏航方向的恢复趋势。
动稳定性判断的是“过程”。即使飞机有回到平衡状态的趋势,这个“回来”的过程是衰减收敛还是越来越剧烈的振荡?这就得靠特征值来判断了——特征值实部为负,扰动是衰减的;实部为正,扰动会发散。这就是MATLAB在这个项目中能发挥最大作用的地方:把判断交给数值计算,快速得到阻尼比和自然频率。
1.3 MATLAB在这个项目里的角色
说白了,MATLAB在这里就是个“计算器加画图板”。飞行力学课本里推导的状态方程是一堆矩阵,手算固然可行,但要是改一个参数(比如重心位置变化)就得重算一遍,效率太低。用MATLAB写一个脚本,参数改掉重新运行,几秒钟就能看到结果变化。
而且MATLAB有很直观的特征值求解函数和画图工具,能直接把特征值投影到复平面上,一眼看出哪些模态是稳定的、哪些在临界状态。课程设计结束后如果想进一步做控制律设计,这些模型也能直接拿来用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从物理模型到数学表达:小扰动线性化
2.1 为什么能把飞机运动拆成线性方程
飞机的完整运动方程是带三角函数的非线性微分方程,直接求解非常麻烦。工程上的做法是:先让飞机在某个平衡点(比如定直平飞)配平,然后假设扰动很小,把方程在配平点附近做泰勒展开并只保留一阶项。
这个假设的物理意义是:扰动足够小的时候,\(\sin\Delta\alpha \approx \Delta\alpha\),\(\cos\Delta\alpha \approx 1\),高阶小量全部忽略。这样非线性方程就变成了线性常系数微分方程,也就是能写成:
\[\dot{x} = A x\]
这种标准形式。这个过程和振动分析里把小角度摆的运动线性化成简谐运动是同一个道理。
2.2 纵向状态方程的标准形式
纵向运动的常用状态变量是:
\[x = [\Delta u, \Delta w, \Delta q, \Delta\theta]^T\]
分别是速度扰动、垂直速度扰动、俯仰角速度扰动和俯仰角扰动。配平状态一般是定常平飞,所以 \(\Delta\) 表示偏离配平值的扰动。
纵向状态矩阵 A 里面各个元素来自量纲气动导数,比如:
- \(X_u\) 是前向速度扰动引起的轴向力变化
- \(Z_u, Z_w\) 是升力变化项
- \(M_u, M_w, M_q\) 是俯仰力矩变化项
- \(-g \sin\theta_0\) 和 \(-g \cos\theta_0\) 是重力项
纵向系统的特征值通常可以分出两组模态:短周期模态和长周期模态(也叫沉浮模态)。短周期对应迎角和俯仰角速度的快速振荡,频率高、阻尼较大;长周期则是速度与俯仰角的缓慢振荡,频率低、阻尼往往很弱,有时候甚至是不稳定的。
2.3 横向状态方程的标准形式
横向运动的常用状态变量是:
\[x = [\Delta\beta, \Delta p, \Delta r, \Delta\phi]^T\]
分别是侧滑角扰动、滚转角速度扰动、偏航角速度扰动和滚转角扰动。注意这里 \(p\) 和 \(r\) 定义在机体坐标系下。
横向状态矩阵里关键的导数包括:
- \(L_\beta\):滚转力矩对侧滑角的导数,对应“上反效应”
- \(N_\beta\):偏航力矩对侧滑角的导数,对应“风向标稳定性”
- \(L_p, L_r, N_p, N_r\):滚转和偏航阻尼导数
横向系统的特征值通常对应三个模态:滚转收敛模态(一个实根)、螺旋模态(一个通常很小的实根或共轭复根)、荷兰滚模态(一对共轭复根)。判断横向稳定性的经典标准就是:螺旋模态不能明显发散,荷兰滚要有足够的阻尼。
2.4 特征值判稳的数学原理
对于线性时不变系统 \(\dot{x} = Ax\),解的形态由矩阵 A 的特征值决定。设特征值为 \(\lambda = \sigma \pm j\omega_d\),对应的时间响应是 \(e^{\sigma t}\sin(\omega_d t + \phi)\)。
- \(\sigma < 0\):响应衰减,系统稳定
- \(\sigma > 0\):响应发散,系统不稳定
- \(\sigma = 0\):临界状态,等幅振荡
阻尼比 \(\zeta\) 和自然频率 \(\omega_n\) 由特征值换算得到:
\[\omega_n = \sqrt{\sigma^2 + \omega_d^2}, \quad \zeta = -\frac{\sigma}{\omega_n}\]
工程上对不同模态的阻尼比有明确要求,比如大型客机的短周期阻尼比一般要大于0.35,荷兰滚阻尼比要大于0.08。这些都可以用MATLAB算出来之后直接对照。
3. MATLAB实操:稳定性判定全流程
3.1 准备飞机参数和气动导数
这一步看着简单,其实是整个项目里最容易出错的地方。要收集的数据包括飞机的基本参数:质量 m、飞行速度 V0、飞行高度对应的空气密度 ρ、机翼面积 S、平均气动弦长 c-bar、翼展 b,以及配平状态的迎角 α0 和俯仰角 θ0。
气动导数一般来自风洞试验、CFD计算或者已有的飞机数据库。这里给出一个典型的中小型飞机示例数据,方便后面演示代码直接用(数值仅为教学演示,不代表真实机型):
质量 m = 50000 kg
飞行速度 V0 = 25 0m/s(约0.75马赫在低空的水平)
机翼面积 S = 100 m²
平均气动弦长 c = 4.5 m
翼展 b = 22 m
空气密度 ρ = 0.905 kg/m³
升力系数 CL = 0.54
阻力系数 CD = 0.042
无量纲气动导数(都是典型量级):
纵向:
C_L_alpha = 5.2 /rad
C_D_alpha = 0.15 /rad
C_m_alpha = -0.8 /rad(静稳定,注意负数)
C_m_q = -8.0 /rad
横向:
C_y_beta = -0.51 /rad
C_l_beta = -0.08 /rad(上反效应,注意负数)
C_n_beta = 0.11 /rad(风向标稳定,正数)
C_l_p = -0.46 /rad
C_n_r = -0.21 /rad
实际项目中,这个表就是报告里最重要的原始数据表。单位问题要格外小心:气动导数通常以每弧度为单位,不是每度。
3.2 装配纵向状态矩阵并求特征值
下面这段MATLAB代码把纵向状态矩阵搭起来。注意参数的命名和单位,建议全程用国际单位制,忽略英制单位。
matlab复制% 纵向稳定性分析
% 基本参数
m = 50000; % kg
V0 = 250; % m/s
rho = 0.905; % kg/m^3
S = 100; % m^2
c_bar = 4.5; % m
g = 9.81; % m/s^2
I_y = 850000; % kg*m^2,俯仰转动惯量
theta0 = 0; % 配平俯仰角,水平平飞
% 纵向稳定导数(每弧度)
CL = 0.54;
CD = 0.042;
CL_alpha = 5.2;
CD_alpha = 0.15;
Cm_alpha = -0.8;
Cm_q = -8.0;
% 动压
qbar = 0.5 * rho * V0^2;
% 量纲导数(采用经典飞行力学公式)
Xu = -qbar*S*(CD + 2*CD) / (m*V0);
Xw = -qbar*S*(CD_alpha - CL) / (m*V0);
Zu = -qbar*S*(CL + 2*CL) / (m*V0);
Zw = -qbar*S*(CL_alpha + CD) / (m*V0);
Zq = -qbar*S*c_bar*CL_alpha / (m*2*V0); % 简单近似处理
Mu = 0;
Mw = qbar*S*c_bar*Cm_alpha / I_y;
Mq = qbar*S*c_bar^2*Cm_q / (I_y*2*V0);
% 装配纵向状态矩阵 A_long
A_long = [Xu Xw 0 -g*cos(theta0);
Zu Zw V0 -g*sin(theta0);
Mu Mw Mq 0;
0 0 1 0];
% 求特征值
eig_long = eig(A_long);
disp('纵向特征值:');
disp(eig_long);
% 计算每个模态的阻尼比和自然频率
for i = 1:length(eig_long)
lambda = eig_long(i);
if abs(imag(lambda)) > 1e-6 % 复特征值
omega_n = abs(lambda);
zeta = -real(lambda)/omega_n;
fprintf('复根: s = %+.4f ± %.4fi,自然频率 = %.4f rad/s,阻尼比 = %.4f\n', ...
real(lambda), abs(imag(lambda)), omega_n, zeta);
else
fprintf('实根: s = %+.4f\n', real(lambda));
end
end
跑完上面这段代码,你会看到典型的纵向结果:一个高频高阻尼的短周期模态(靠近虚轴左侧,自然频率可能在2~4 rad/s),一个低频低阻尼的长周期模态(可能非常靠近虚轴,甚至出现实部为正的发散情况)。
这里特别要提醒一下,Xw 和 Zu 的表达式在很多教材里写法不一样,因为不同的教材对 X 和 Z 的方向定义有差异。建议你在报告里写明自己使用的公式来源,避免符号上的争议。
3.3 装配横向状态矩阵并对比三种模态
横向矩阵的代码逻辑类似,只是状态变量和导数的位置不同。
matlab复制% 横向稳定性分析
% 横向转动惯量
I_x = 250000; % kg*m^2
I_z = 900000; % kg*m^2
I_xz = 28000; % kg*m^2,惯性积
% 横向稳定导数(每弧度)
Cy_beta = -0.51;
Cl_beta = -0.08;
Cn_beta = 0.11;
Cl_p = -0.46;
Cl_r = 0.07;
Cn_p = -0.03;
Cn_r = -0.21;
% 量纲导数(简化模型,忽略惯性积的完整耦合处理,适合教学演示)
Y_beta = qbar*S*Cy_beta / m;
L_beta = qbar*S*b*Cl_beta / I_x;
N_beta = qbar*S*b*Cn_beta / I_z;
L_p = qbar*S*b^2*Cl_p / (I_x*2*V0);
L_r = qbar*S*b^2*Cl_r / (I_x*2*V0);
N_p = qbar*S*b^2*Cn_p / (I_z*2*V0);
N_r = qbar*S*b^2*Cn_r / (I_z*2*V0);
% 重力项
g_term_phi = g / V0;
% 装配横向状态矩阵 A_lat
A_lat = [Y_beta g_term_phi 0 g*cos(theta0)/V0;
L_beta L_p L_r 0;
N_beta N_p N_r 0;
0 1 0 0];
eig_lat = eig(A_lat);
disp('横向特征值:');
disp(eig_lat);
运行之后,你会看到三类特征值:
- 一个接近负实轴的较大负实根,对应滚转收敛模态,阻尼大、收敛快
- 一个非常靠近原点的小实根或虚部很小的复根,对应螺旋模态,通常非常缓慢
- 一对共轭复根,对应荷兰滚模态
工程上的判断标准是:螺旋模态时间常数要大于某个值(比如几十秒以上才算合格),荷兰滚阻尼比越大越好。如果螺旋模态明显发散,或者荷兰滚阻尼比过低,飞机的横向飞行品质就会很差。
3.4 用特征值分布图直观判断
算出特征值之后,建议画一张特征值分布图。把实部作为横轴、虚部作为纵轴,所有特征值落在左半平面就是稳定的。
matlab复制figure;
plot(real(eig_long), imag(eig_long), 'bx', 'MarkerSize', 10, 'LineWidth', 1.5);
hold on;
plot(real(eig_lat), imag(eig_lat), 'ro', 'MarkerSize', 10, 'LineWidth', 1.5);
grid on;
xlabel('实部 (1/s)');
ylabel('虚部 (rad/s)');
legend('纵向模态', '横向模态');
title('飞机纵向和横向模态特征值分布');
yline(0); xline(0);
这张图放进报告里非常直观,一眼就能看出系统是否稳定。
3.5 改变重心位置看稳定性趋势
飞机设计中有一个非常经典的分析:重心位置对稳定性的影响。重心后移,气动焦点和重心的距离缩小,\(C_{m\alpha}\) 的绝对值变小,纵向静稳定性减弱。你可以写一个循环,让重心从平均气动弦的15%移到35%,观察特征值变化趋势。
matlab复制cg_positions = 0.15:0.02:0.35; % 重心相对平均气动弦的位置
omega_short = zeros(size(cg_positions));
zeta_short = zeros(size(cg_positions));
for i = 1:length(cg_positions)
% 用当前重心位置修正 Cm_alpha
Cm_alpha_current = Cm_alpha - 5.2 * (cg_positions(i) - 0.25);
Mw = qbar*S*c_bar*Cm_alpha_current / I_y;
A_long(3,2) = Mw;
eig_temp = eig(A_long);
for j = 1:length(eig_temp)
if imag(eig_temp(j)) > 1e-6
omega_short(i) = abs(eig_temp(j));
zeta_short(i) = -real(eig_temp(j))/abs(eig_temp(j));
break;
end
end
end
figure;
yyaxis left;
plot(cg_positions, omega_short, '-o');
ylabel('短周期自然频率 (rad/s)');
yyaxis right;
plot(cg_positions, zeta_short, '-s');
ylabel('短周期阻尼比');
xlabel('重心位置 (MAC%)');
grid on;
这段代码会生成一条趋势曲线,你能清楚看到重心后移后阻尼比的变化方向。报告中这种参数扫描图很加分,因为它展示了你不仅会算一个点,还会做参数影响分析。
4. 常见问题与排查技巧实录
4.1 气动导数符号和单位导致结果全错
这是我在实际项目中遇到最多的问题。很多同学的代码逻辑完全正确,但结果却“妖怪”——纵向第一个特征值就是正十几,飞机看起来完全没法飞。排查下来,八成是导数符号写反了。
Cm_alpha 在绝大多数情况下是负数(静稳定飞机),如果你写成了正数,特征值必然出现正实部。还有就是角度单位,气动导数来自文献时,有些资料用“每度”而有些用“每弧度”,差出57.3倍。解决方法是:拿到导数先统一换算成“每弧度”,再写进代码。
注意:代码里所有角度相关量,包括配平迎角、俯仰角,全部用弧度制。MATLAB三角函数默认接受弧度,这是最容易忽略的细节。
4.2 特征值实部正负判断反了
有些教材采用“exp(-λt)”的约定,有些采用“exp(λt)”的约定,导致你看到特征值正负号的意义完全不同。飞行力学里普遍采用 \(x = x_0 e^{\lambda t}\) 来讨论,λ 实部为正就不稳定。如果你在某份文献里看到相反结论,先确认它的约定再说。
报告里最好把这句写清楚:“按照 \(e^{\lambda t}\) 约定,实部为负表示扰动衰减。”
4.3 纵向和横向模态混叠怎么办
当横向和纵向的特征值比较接近时,直接看特征值很难区分哪个是哪个模态。最可靠的办法是看特征向量。
matlab复制[V, D] = eig(A_long);
% 找到短周期模态的特征值索引,查看对应特征向量的主导状态
eig_vals = diag(D);
[~, idx] = max(abs(eig_vals));
v_dominant = V(:, idx);
disp('主导特征向量:');
disp(v_dominant);
比如纵向短周期模态的特征向量中,迎角扰动和俯仰角速度扰动分量大;长周期模态中,速度扰动分量通常更突出。横向模态同理:荷兰滚模态侧滑角分量大,螺旋模态滚转角分量占主导。
4.4 初始化模型时忽略惯性积导致偏差
我前面示例代码用了简化模型,忽略惯性积 \(I_{xz}\)。对于课程设计级别的研究,这个精度通常够用。但如果你做的是比较严格的飞行品质分析,务必把惯性积耦合项加进去,不然荷兰滚模态的频率和阻尼比会不太准。
完整的横向方程中,\(\dot p\) 和 \(\dot r\) 会通过惯性积耦合,需要先做矩阵求逆,把状态方程转换成标准形式。具体表达式可以参考《Aircraft Dynamics and Automatic Control》这类教材,里面有完整的推导过程。
4.5 报告写作建议
这类项目通常要求“源码+报告”一起交付,报告质量直接影响成绩。建议报告包含以下几个板块:
- 物理背景与研究对象说明,简述纵向/横向稳定性定义
- 小扰动线性化推导过程,列出状态方程和矩阵中各元素的来源
- 代码实现的框架说明,重点讲清楚哪些参数是输入、哪些是输出
- 结果分析,包括特征值表、模态归类、阻尼比和自然频率计算、特征值分布图
- 参数影响分析,比如重心位置扫描,验证理论预期
- 结论与展望,说明模型简化局限
表格是报告里的好工具,比如把纵向特征值、短周期自然频率、短周期阻尼比、长周期自然频率、长周期阻尼比列成一张表,再配上规范要求值,老师一眼就能看出你研究结论的合理性。
5. 一些项目扩展与提升思路
这套模型做完之后,别急着收工。如果时间允许,可以往两个方向扩展一下。
第一个方向是加控制律。现在你已经有了线性模型,可以在状态空间模型上加LQR或者PID控制器,看控制增益如何改变闭环特征值。也就是把开环不稳定或阻尼不足的模态通过反馈拉回来,这个过程在MATLAB里用 lqr 函数非常顺畅。
第二个方向是加扰动响应仿真。用 lsim 或者 initial 函数,给飞机一个迎角初值或者滚转角初值,画出它回到配平状态的时间历程曲线。把短周期和长周期的振荡过程可视化出来,报告里放两张这样的图,说服力比单纯列特征值要强得多。
我个人在实际操作中的体会是:这类稳定性分析项目,真正有价值的不在于把代码跑通,而在于你能看懂每个矩阵元素背后的物理意义。当你把重心后移,看到短周期阻尼比跟着下降,再联系到“放宽静稳定性”这个设计理念,整个知识体系就串起来了。这才是这类作业真正想让你学到的东西。
