一: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 ,将飞机跑起来,同时运行上述程序即可得下图: