一:flightgear通过UDP协议输出飞行态势数据
首先创建输出配置文件(xml格式),这里命名output.xml
以下是文件内容:
<?xml version="1.0"?>
<PropertyList>
<generic>
<output>
<line_separator>newline</line_separator>
<var_separator>newline</var_separator>
<binary_mode>false</binary_mode>
<chunk>
<name>MACH Number</name>
<format>M%4.1f</format>
<type>float</type>
<node>/velocities/mach</node>
</chunk>
<chunk>
<name>Ground Speed</name>
<format>GS:%3dkts</format>
<node>/instrumentation/gps/indicated-ground-speed-kt</node>
</chunk>
<chunk>
<name>G Load</name>
<format>G%2.1f</format>
<type>float</type>
<node>/accelerations/pilot/z-accel-fps_sec</node>
<factor>-0.03108095</factor>
<damp>1.0</damp>
</chunk>
<chunk>
<name>AGL</name>
<format>AGL%4.0f</format>
<type>float</type>
<node>/position/altitude-agl-ft</node>
</chunk>
</output>
</generic>
</PropertyList>
<chunk></chunk>之间决定了要输出的内容,其中<name>仅仅是为了区分各个chunk没具体意义,不用管它;<format>是输出格式设置,当输出变量为float类型时需要添加<type>float</type>标记;<node>是输出数据来源,可以在HUD.xml文件中查到,<factor>,<damp>都是对原始数据进行的操作,将它与HUD.xml中相同元素名称对应就可以了。如”G load”在HUD.xml中:
那么output.xml中”G load”中<node>就对应上图中的<property>,上图中有<factor>,<damp>那么output.xml中的”G load”也需要添加。
配置文件建好之后,将文件放在C:\ProgramFiles\FlightGear 2017.3.1\data\Protocol下,然后在flightgear启动界面命令行下添加以下命令:
--httpd=5500
--generic=socket,out,5,localhost,5500,udp,output
5是输出频率单位是赫兹(这个对不对?请赐教),5500是输出端口,udp是协议类型,output是输出文件名(即上面讲到的output.xml的名字)。
二:接收数据
以下是用C++写的接收UDP数据的代码(Copy from others )
#include"stdafx.h"
#include<stdio.h>
#include<winsock.h>
#include<conio.h>
//创建新的套接字之前需要调用一个引入Ws2_32.dll库的函数,否则服务器和客户端连接不上
#pragmacomment(lib,"ws2_32.lib")
int main(intargc,char*argv[])
{
WSADATA wsaData; //指向WinSocket信息结构的指针
SOCKET sockListener;
SOCKADDR_IN sin, saClient; //设置两个地址,sin用来绑定
//saClient用来从广播地址接收消息
charcRecvBuff[800]; //定义接收缓冲区
intnSize, nbSize;
intiAddrLen = sizeof(saClient);
if(WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) //进行WinSocket的初始化
{
printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1
return-1;
}
sockListener= socket(AF_INET, SOCK_DGRAM,0);
sin.sin_family= AF_INET;
sin.sin_port= htons(5500); //发送端使用的发送端口,可以根据需要更改
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockListener, (SOCKADDRFAR*)&sin, sizeof(sin)) != 0)
{
printf("Can't bind socket to local port!Program stop.\n");//初始化失败返回-1
return-1;
}
while(1)
{
nSize= sizeof (SOCKADDR_IN);
if((nbSize = recvfrom(sockListener, cRecvBuff, 800, 0,
(SOCKADDRFAR *)&saClient, &nSize)) == SOCKET_ERROR) //若接收失败则提示错误
{
printf("Recive Error");
break;
}
cRecvBuff[nbSize]= '\0'; //字符串终止
printf("%s\n", cRecvBuff); //显示所接收到的字符串
}
return0;
}
三:启动flightgear ,将飞机跑起来,同时运行上述程序即可得下图: