如何用Matplotlib在飞行轨迹动画中添加姿态(滚转/俯仰/偏航)标识
实现带姿态的3D飞行轨迹动画(Matplotlib方案)
Matplotlib完全可以实现你需要的需求,下面是修改后的完整脚本,能够在轨迹末端绘制随roll/pitch/yaw实时调整姿态的三角形飞机图标:
from matplotlib.animation import FuncAnimation import matplotlib.pyplot as plt import pandas as pd import numpy as np def animate(i, ax): # 读取飞行数据 data = pd.read_csv('flight_data.csv') lat = data['latitude'].values lon = data['longitude'].values alt = data['altitude'].values roll = data['roll'].values pitch = data['pitch'].values yaw = data['yaw'].values # 清空当前轴,准备绘制新帧 ax.cla() # 绘制完整飞行轨迹 ax.plot(lon, lat, alt, label='Aircraft Trajectory') # 处理最新的飞机位置与姿态 if len(data) > 0: # 获取轨迹末端的位置和姿态参数 current_pos = np.array([lon[-1], lat[-1], alt[-1]]) current_roll = roll[-1] current_pitch = pitch[-1] current_yaw = yaw[-1] # 定义基础飞机三角形模型(本地坐标系原点,机头朝前) plane_base = np.array([ [0.0001, 0, 0], # 机头 [-0.00003, 0.00005, 0], # 左翼 [-0.00003, -0.00005, 0] # 右翼 ]) # 构建姿态旋转矩阵(航空标准顺序:偏航→俯仰→滚转) # 偏航(绕Z轴)旋转矩阵 yaw_mat = np.array([ [np.cos(current_yaw), -np.sin(current_yaw), 0], [np.sin(current_yaw), np.cos(current_yaw), 0], [0, 0, 1] ]) # 俯仰(绕Y轴)旋转矩阵 pitch_mat = np.array([ [np.cos(current_pitch), 0, np.sin(current_pitch)], [0, 1, 0], [-np.sin(current_pitch), 0, np.cos(current_pitch)] ]) # 滚转(绕X轴)旋转矩阵 roll_mat = np.array([ [1, 0, 0], [0, np.cos(current_roll), -np.sin(current_roll)], [0, np.sin(current_roll), np.cos(current_roll)] ]) # 组合旋转矩阵并应用到飞机模型 rotation_mat = roll_mat @ pitch_mat @ yaw_mat plane_transformed = (rotation_mat @ plane_base.T).T + current_pos # 绘制带填充的飞机三角形 ax.plot_trisurf(plane_transformed[:,0], plane_transformed[:,1], plane_transformed[:,2], color='red', alpha=0.8) # 设置坐标轴标签 ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') ax.set_zlabel('Altitude') plt.legend(loc='upper left') # 创建3D绘图轴 ax = plt.figure().add_subplot(projection='3d') # 启动动画,每500ms刷新一次 ani = FuncAnimation(plt.gcf(), animate, fargs=(ax, ), interval=500) plt.show()
关键说明
- 模型尺寸适配:因为经纬度数值量级很小,飞机模型的顶点坐标设置为
0.0001量级,确保和轨迹比例匹配,避免飞机过大或过小。 - 姿态旋转顺序:代码采用航空领域标准的姿态变换顺序(偏航→俯仰→滚转),如果你的CSV中姿态参数的定义顺序不同,需要调整旋转矩阵的相乘顺序。
- 性能优化提示:原代码每次读取整个CSV文件,当数据量较大时会降低动画流畅度,建议记录已读取的行数,使用
pd.read_csv的skiprows参数每次仅读取新增数据行。
内容的提问来源于stack exchange,提问作者Dobid
相关产品推荐
相关产品推荐

