Bootstrap

【matlab&python】飞行器简单状态空间模型微分步长仿真程序参考

前言

转眼开始写博客已经一年了,这篇本来是寒假前就想发的,谁知一拖就是几个月。

之前老是想在网上找关于飞行器相关的仿真程序,但是一直也没有找到比较经典、合理的。给平时的工作带来了困扰,这部分的代码我也是经过看师兄的程序,看论文,整理出一个比较简单的框架,而且那会复现了别人论文里的结果,所以后面的有些工作也建立在这个之上,分享出来与大家共同进步。

来源

代码中所用到的模型来自:张勇. 面向控制的高超声速飞行器一体化设计[D]. 南京航空航天大学, 2012.
第三章,3.2.2节的内容。

附上参考文献中的结果以供对比:
在这里插入图片描述
在这里插入图片描述

MATLAB

代码

话不多说,直接上MATLAB代码,我的注释也算是比较详细了,切换文件夹一类的改成自己电脑上的相应路径就好,纯属个人习惯。

思路很简单,先定义参数,后定义模型。接着在循环中不断求解状态微分量,更新,引入状态量,模型就“动起来了”

% 尝试用之前现有的数据实现传统的跟踪控制器设计
% 状态空间模型步长加入控制律仿真
% 《面向控制的高超声速飞行器一体化设计》张勇
% 2021年2月6日  WJJ
%状态空间模型解算
% 首先套用论文中的刚体模型系数矩阵
clear all;
clc;
close all;
%% 状态量初始化
cd ('D:\OneDrive - 徐州开放大学\NPU\program\Morphing');

% 论文中的平衡点输入、状态 8Ma,26000m
uStable = [0.323;0.203];
xStable = [2392.48,0.020,0,26000,0.020];
xInitial = [2425,0.015,0,26100,0.015];          % 初始状态
% V = xStable(1)+ 500;                   %初始化状态  
% alpha = xStable(2)+ 4;
% omegaz = xStable(3)+ 1;
% height = xStable(4)+ 2000;
% theta = xStable(5)+ 3;
V = xInitial(1);                   %初始化状态  
alpha = xInitial(2);
omegaz = xInitial(3);
height = xInitial(4);
theta = xInitial(5);
deltat = uStable(1);            %初始化控制输入
deltae = uStable(2);

% 状态矩阵A
A = [-0.0036, -11.929, 0, -0.0000026, -9.727;...
-0.0000015, -0.1087, 1, 0, 0;...
-0.0003, 16.122, 0, 0, 0;...
0, -2392.48, 0, 0, 2392.48;...
0, 0, 1, 0, 0];

% 控制矩阵B
B=[ 14.2399, -0.0014, 0.1355, 0, 0;
-16.669, -0.0166, -8.273, 0, 0]';

C = eye(5);           %全输出
D = zeros(5,2);

states = {'V','alpha','omegaz','height','theta'};   %定义状态变量速度、弹道倾角、高度、攻角、俯仰角速度
inputs = {'sigma','deltae'};        %定义输入变量 水平舵偏角与油门阈值
outputs = {'V','theta','height','alpha','omegaz'};  %定义输出

sys = ss(A,B,C,D,'statename',states,'inputname',inputs,'outputname',outputs);   %输出并显示系统状态方程模型

co = ctrb(A,B);      %检验系统的能控性,若满秩则能控  可控
ob = obsv(A,C);    %检验系统的可观性,若满秩则可观   能观


% 论文中的LQR状态反馈增益矩阵
Klqr =[-0.003, 1.1729, -0.0114, 0, -1.2358;...
-0.0005, -0.7145, 0.9934, 0.0003, 4.8024];


%   Simulation parameters
step = 0.1;               %应该是步长
t = 0;                      %时间
dR  = -1;               %后面重新赋值了,相对距离
n = 1;                      %步数
temp = 0;               %和舵偏有关 初始舵偏角
%% 仿真循环
while (t < 500 && height > 0)
%       数据解算
    Vehicle_states(n,:) = [V;alpha;omegaz;height;theta];     %状态量初始化
    Vehicle_del_states(n,:) = Vehicle_states(n,:) - xStable;            %状态变化量初始化
%     Control_del_states(n,:) = [deltat;deltae] - uStable;    %控制变化量初始化
    Control_del_states(n,:) = Klqr * Vehicle_del_states(n,:)';           %尝试控制量变化量直接用公式解算出来,
    Del_states(n,:) = A * Vehicle_del_states(n,:)' + B * Control_del_states(n,:)';
%     Control_states(n,:) = uStable + Klqr * Vehicle_del_states(n,:)';          %控制律更新解算
%     deltae = deltae + unifrnd (-1, 1);       %加入扰动
%     deltat = deltat + unifrnd (-4, 4);
    %   状态更新
    del_V = Del_states(n,1);
    del_alpha = Del_states(n,2);
    del_omegaz = Del_states(n,3);
    del_height = Del_states(n,4);
    del_theta = Del_states(n,5);
    states_old = [V;alpha;omegaz;height;theta];      %导弹参数 速度 弹道倾角 高度 攻角 俯仰角速度   
    del = [del_V;del_alpha;del_omegaz;del_height;del_theta];                 %微分量
    states_new = states_old + del * step;           %更新 赋值 old 和del一个行向量一个列向量导致出来是矩阵
    V = states_new(1);
    theta = states_new(5);
    height = states_new(4);
    alpha = states_new(2);
    omegaz = states_new(3);
    %  控制更新
    Control_states(n,:) = Control_del_states(n,:) + uStable';        %实际控制量
%     deltat = Control_states(n,1);
%     deltae = Control_states(n,2);
%     这一部分其实可以忽略,后来发现其实没什么用
%     舵偏角约束  
    if deltae <= -30
        deltae = -30;
    end
    if deltae >= 30
        deltae = 30;
    end
%     油门开度约束
    if deltat <= 0
        deltat = 0;
    end
    if deltae >= 100
        deltae = 100;
    end
    
    %  时间更新
    Time(n) = t;   %时间记录
    t = t + step;  %仿真步长
    n = n + 1;  %计数+1
end
%%  绘图
Drawcon;

绘图子程序,后来习惯放在额外的程序中增加通用性,调试起来也方便,放到同一个文件夹下即可,平时我论文里用图也大都是这种格式,经过了一番摸索,颜值尚可。

figure;
% 速度
subplot(5,1,1);plot(Time,Vehicle_states(:,1),'linewidth',1.5);
%axis([0 100 1400 1600]) ;
grid on;
% title(['速度为 ',num2str(v),' m/s时的响应曲线']);
% title(['Velocity =  ',num2str(V),' m/s'],'Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$V(m/s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);
% 弹道倾角
subplot(5,1,2);plot(Time,Vehicle_states(:,2),'linewidth',1.5);
%axis([0 100 -1 1]) ;
grid on;
% title('弹道倾角响应曲线');
% title('Pitch angle','Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$\alpha(^\circ)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');

set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);
% 高度
subplot(5,1,3);plot(Time,Vehicle_states(:,3),'linewidth',1.5);
%axis([0 100 18500 21500]) ;
grid on;
% title(['高度为 ',num2str(h),' m时的响应曲线']);
% title(['Altitude =  ',num2str(h),' m'],'Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$\omega_z(^\circ/s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');

set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);
% 攻角
subplot(5,1,4);plot(Time,Vehicle_states(:,4),'linewidth',1.5);
%axis([0 100 -1 1]) ;
grid on;
% title('攻角响应曲线');
% title('Angle of attack','Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$h(m)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);
% 俯仰角速度
subplot(5,1,5);plot(Time,Vehicle_states(:,5),'linewidth',1.5);
%axis([0 100 -1 1]) ;
grid on;
% title('俯仰角速度响应曲线');
% title('Pitch rate','Fontname', 'Times New Roman','FontSize',14);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$\theta(^\circ)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);

figure;
% 速度
subplot(5,1,1);plot(Time,Del_states(:,1),'linewidth',1.5);
%axis([0 100 1400 1600]) ;
grid on;
% title(['速度为 ',num2str(v),' m/s时的响应曲线']);
% title(['Del_Velocity =  ',num2str(V),' m/s'],'Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$\dot{V}(m/s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);
% 弹道倾角
subplot(5,1,2);plot(Time,Del_states(:,2),'linewidth',1.5);
%axis([0 100 -1 1]) ;
grid on;
% title('弹道倾角响应曲线');
% title('Del_Pitch angle','Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$\dot{\alpha}(^\circ)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');

set(gca,'FontName','Times New Roman','FontSize',14,'linewidth',1.5);
% 高度
subplot(5,1,3);plot(Time,Del_states(:,3),'linewidth',1.5);
%axis([0 100 18500 21500]) ;
grid on;
% title(['高度为 ',num2str(h),' m时的响应曲线']);
% title(['Del_Altitude =  ',num2str(h),' m'],'Fontname', 'Times New Roman','FontSize',16);
xlabel('$T(s)$','FontName','Times New Roman','FontSize',14,'Interpreter','latex');
ylabel('$\dot{\omega_z}(^\circ/s)$','FontName
;