python接收flightgear数据
1.创建output.xml文件,配置所需要输出的参数如下
xml
<?xml version="1.0" encoding="UTF-8"?>
<PropertyList>
<generic>
<output>
<line_separator>newline</line_separator>
<var_separator>newline</var_separator>
<binary_mode>false</binary_mode>
<chunk>
<name>alpha-rad</name>
<format>%.2f</format>
<type>float</type>
<node>/fdm/jsbsim/aero/alpha-rad</node>
<factor>57.6</factor>
</chunk>
<chunk>
<name>u-aero-fps</name>
<format>%.2f</format>
<node>/fdm/jsbsim/velocities/u-aero-fps</node>
<factor>0.3048</factor>
</chunk>
<chunk>
<name>Nz</name>
<format>%.2f</format>
<type>float</type>
<node>/fdm/jsbsim/accelerations/Nz</node>
</chunk>
<chunk>
<name>h-sl-meters</name>
<format>%.2f</format>
<type>float</type>
<node>/fdm/jsbsim/position/h-sl-meters</node>
</chunk>
</output>
</generic>
</PropertyList>
2.将output.xml文件放到正确的位置
放在安装目录的FlightGear 2020.3\data\Protocol下如图所示
注意:
对于alpha-rad(迎角角度),添加了一个因子57.6,用于将弧度转换为度(实际上应该是57.2958,因为180/π ≈ 57.2958)。
对于u-aero-fps(x方向速度),添加了一个因子0.3048,用于将英尺每秒转换为米每秒
3.将该命令复制到附加指令中:
--httpd=5501
--generic=socket,out,5,localhost,5501,udp,output
如下图所示
4.Python编写接收数据代码:
python代码
python
import socket
# FlightGear UDP 端口通常是5501,但可以在FlightGear配置中更改
fg_ip = '127.0.0.1' # FlightGear运行的计算机的IP地址
fg_port = 5501
# 创建一个UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定到本地端口以接收UDP数据
sock.bind(('', fg_port))
print(f"Listening for FlightGear data on {fg_ip}:{fg_port}...")
# 持续监听数据
while True:
data, addr = sock.recvfrom(1024) # Buffer size is 1024 bytes
text_data = data.decode('utf-8') # 解码为字符串
print(text_data) # 打印接收到的数据
结果如图:
输出数据:
xml
迎角角度 1.0
x方向速度: 35 m/s
Nz 1.0
高度: 239 米
5.PyQt绘制曲线
代码
python
import sys
import socket
import matplotlib.pyplot as plt
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5.QtCore import QTimer
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rc('font', size=14)
plt.rc('axes', titlesize=16) # 标题大小
plt.rc('axes', labelsize=14) # 轴标签大小
plt.rc('xtick', labelsize=12) # X 轴刻度标签大小
plt.rc('ytick', labelsize=12) # Y 轴刻度标签大小
plt.rc('legend', fontsize=12) # 图例字体大小
# FlightGear UDP 端口通常是5501,但可以在FlightGear配置中更改
fg_ip = '127.0.0.1' # FlightGear运行的计算机的IP地址
fg_port = 5501
# 创建一个UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', fg_port))
class FlightDataChart(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.data_storage = {
'alpha': [],
'u_aero': [],
'Nz': [],
'height': []
}
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_data)
self.timer.start(100) # 更新间隔为100毫秒
def initUI(self):
self.setWindowTitle('Flight Data Chart')
self.setGeometry(100, 100, 800, 1000)
# 创建 matplotlib 图表
self.figure = Figure()
self.canvas = FigureCanvas(self.figure)
self.setCentralWidget(self.canvas)
# 创建子图
self.ax1 = self.figure.add_subplot(411)
self.ax2 = self.figure.add_subplot(412)
self.ax3 = self.figure.add_subplot(413)
self.ax4 = self.figure.add_subplot(414)
def update_data(self):
try:
data, addr = sock.recvfrom(1024) # Buffer size is 1024 bytes
text_data = data.decode('utf-8') # 解码为字符串
# 解析数据
values = text_data.strip().split('\n')
alpha = float(values[0])
u_aero = float(values[1])
Nz = float(values[2])
height = float(values[3])
# 存储数据
self.data_storage['alpha'].append(alpha)
self.data_storage['u_aero'].append(u_aero)
self.data_storage['Nz'].append(Nz)
self.data_storage['height'].append(height)
# 限制数据长度
max_length = 100
for key in self.data_storage:
if len(self.data_storage[key]) > max_length:
self.data_storage[key] = self.data_storage[key][-max_length:]
# 清除之前的图像
self.ax1.clear()
self.ax2.clear()
self.ax3.clear()
self.ax4.clear()
# 绘制新的图像
self.ax1.plot(self.data_storage['alpha'], label='迎角角度')
self.ax2.plot(self.data_storage['u_aero'], label='x方向速度 (m/s)')
self.ax3.plot(self.data_storage['Nz'], label='Nz')
self.ax4.plot(self.data_storage['height'], label='高度 (米)')
# 设置图例
self.ax1.legend()
self.ax2.legend()
self.ax3.legend()
self.ax4.legend()
# 刷新画布
self.canvas.draw()
except Exception as e:
print(f"Error: {e}")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = FlightDataChart()
ex.show()
sys.exit(app.exec_())