发布时间:2025-12-09 11:55:57 浏览次数:1
python实现飞行控制仿真(二)——三自由度仿真_python 飞行仿真_风雨潇潇一书生的博客-CSDN博客
[基于深度强化学习的无人机对战战术决策的研究 ](D:\CNKI E-Study\18761606609\Literature\TempRead\基于深度强化学习的无人机对战战术决策的研究_胡真财.caj)
将无人机简化为三维空间内的一个质点,为了将研究重点聚焦于格斗决策方法上的研究,本文对无人机的飞行模型设计做出如下四点假设: (1)无人机在飞行过程中不考虑空气阻力,也不考虑空气的流速,也就是说无人机的速度仅仅由自身的机动动作决定。
(2)无人机在飞行过程中没有侧滑,即侧滑角恒等于0。
(3)无人机的质量为恒定值,重力加速度,空气密度等因素不随飞行环境的变化而变化。
(4)地面参考系始终处于静止状态,忽略地球的自转对于建模的影响。 基于以上的设定,定义出无人机在地面惯性坐标系下的三维空间运动学方程如下:
\[\begin{aligned}& \frac{d x}{d t}=v \cos \theta \cos \psi \\& \frac{d y}{d t}=v \cos \theta \sin \psi \\& \frac{d z}{d t}=v \sin \theta \\& \frac{d v}{d t}=g\left(N_x-\sin \theta\right) \\& \frac{d \theta}{d t}=\frac{g}{v}\left(N_z \cos \varphi-\cos \theta\right) \\& \frac{d \psi}{d t}=\frac{g N_z \sin \varphi}{v \cos \theta} \\\end{aligned}\]方程组中的每一项分别表示 UCAV 三维空间坐标值、飞行速率、航向角和轨迹角的一阶微分方程, 决定了格斗过程中飞行器状态更新计算的 方法。
另一种表示,只是符号变了,上式子中的\(\theta\)为下面的\(\gamma\) , \(\varphi\)为\(mu\),
\(N_x\) 为飞行器的切向过载,表示的是飞行器在前进速度方向上受到的推力和自身重力的比值,切向过载可以改变飞行器的速度大小, \(N_x\) 可以实现飞行器加速、减速、或者匀速率飞行的控制;
\(N_z\) 是飞行器的法相过载, 表示飞行 器受到的与其机身平面垂直且方向向上的过载, 能够提供飞行器所需的升力,\(N_z\) 可以控制飞行器的俯冲, 拉起和平稳飞行的控制, 以改变飞行器的垂直高度。
\(\varphi\) 为机体的滚转角, 表示的是机体绕自身速度方向的夹角, 一般固定翼飞 滚转角实现侧身的效果, 可以为固定翼飞行器提供转弯所需要的推力 \({ }^{[48]}\), 以实现更有效的转弯。
控制量为 切向过载 \(N_x\) 法向过载\(N_z\) 滚转角 \(\varphi\)也就是图片里的\(mu\)
状态量为: 三维空间坐标值\((x,y,z)\) ,飞行速率、航迹角 、航向角
给定初始状态
三维空间坐标值、飞行速率、航迹角 、航向角
\[x,y,z,v,\gamma,\varphi\]state = [x,y,z,v,gamma,varphi]输入 : 控制量 切向过载 、法向过载、滚转角
\[N_x 、 N_z、 \mu\]control = [Nx , Nz , mu]代码返回: 下一时间(一个仿真步长)的状态量
# -*- coding: utf-8 -*-"""@author : zuti@software : PyCharm@file : 3_run_func.py@time : 2023/3/23 19:46@desc :"""import matplotlib.pyplot as pltimport numpy as npfrom scipy.integrate import odeintplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseplt.rcParams.update({'font.size': 12})# 初始姿态init_velocity, init_gamma, init_varphi = 260., 3.14 / 10., 0.init_x, init_y, init_z = 0., 0., 1000. # 初始位置# todo 三个控制量Nx = 3.0Nz = 2.mu = 3.14 / 12state = [init_x, init_y, init_z, init_velocity, init_gamma, init_varphi]control = [Nx, Nz, mu]time = 1 # 秒 总时间n = 10 # 仿真步数t = np.linspace(0, time, n) # 仿真步长def dmove2(x_input, t, control): g = 9.81 # 重力加速度 velocity, gamma, fai = x_input nx, nz, gunzhuan = control velocity_ = g * (nx - np.sin(gamma)) # # 米每秒 gamma_ = (g / velocity) * (nz * np.cos(gunzhuan) - np.cos(gamma)) # 米每秒 fai_ = g * nz * np.sin(gunzhuan) / (velocity * np.cos(gamma)) return np.array([velocity_, gamma_, fai_])def update_position(state, control, time=1, n=10): """ :param state: 初始状态 :param control: 控制量 :param time: 仿真时长 :param n: 仿真步数 :return: """ t = np.linspace(0, time, n) # 仿真步长 dt = t[1] - t[0] state_list = np.zeros((n, 6)) # 轨迹长度 state_list[0] = state # 轨迹列表第一个元素为初始状态 x,y,z,velocity, gamma, varphi = state_list[0] for k in range(1, n): tspan = [t[k - 1], t[k]] st = odeint(dmove2, (velocity, gamma, varphi), tspan, args=([control[0], control[1], control[2]],)) velocity, gamma, varphi = st[1, :] dx = velocity * np.cos(gamma) * np.sin(varphi) * dt dy = velocity * np.cos(gamma) * np.cos(varphi) * dt dz = velocity * np.sin(gamma) * dt x = x + dx state_list[k, 0] = x y = y + dy state_list[k, 1] = y z = z + dz state_list[k, 2] = z state_list[k, 3] = velocity state_list[k, 4] = gamma state_list[k, 5] = varphi return state_list#测试运动学方程state_list = update_position(state,control)print(f'轨迹 {state_list}')#绘制图像fig = plt.figure()ax1 = fig.add_subplot(221,projection='3d')ax1.plot(state_list[:, 0], state_list[:, 1], state_list[:, 2])ax1.set_title('trajectory 轨迹')ax1.set_xlabel('X')ax1.set_ylabel('Y')ax1.set_zlabel('Z')ax2 = fig.add_subplot(222)ax2.plot(state_list[:,3])ax2.set_title('velocity 速度')ax3 = fig.add_subplot(223)ax3.plot(state_list[:,4])ax3.set_title('gamma 航迹倾角')ax3 = fig.add_subplot(224)ax3.plot(state_list[:,5])ax3.set_title('varphi 航向角')#plt.savefig('test.jpg')plt.show()