X-Plane
X-Plane面向个人的比较流行的飞行模拟软件之一,用户可以利用其自带的工具或者第三方插件来做一些飞行仿真方面的二次开发,比如飞机位置姿态等数据输出、外部程序控制飞机舵面角度、飞机机模(系统仿真、气动仿真)开发、机场地景开发等等。
X-Plane官网:https://www.x-plane.com/
X-Plane SDK文档:https://developer.x-plane.com/sdk/
XPlaneConnect
XPlaneConnect是NASA开源的一个基于X-Plane SDK开发的开源研究工具,其中包含了两个部分,一个是X-Plane的插件XPlaneConnect.xpl,这个插件需要手动放在X-Plane的安装目录内,X-Plane启动时会调用该插件;一个是与XPlaneConnect.xpl进行UDP通信的库,包括C、JAVA、MATLAB、Python等编程语言,并且提供了许多例程。用户可以基于XPlaneConnect快速进行二次开发,包括数据读写、飞行暂停/恢复、设置飞机位置和姿态等等。
XPlaneConnect:https://github.com/nasa/XPlaneConnect
开发步骤(C/C++)
- 在https://github.com/nasa/XPlaneConnect 下载XPlaneConnect插件和源代码。
- 将XPlaneConnect.zip插件解压并复制到X-Plane安装目录下的/Resources/plugins/目录,然后打开X-Plane。
- 创建一个C/C++工程,将XPlaneConnect-1.3-rc6.zip解压,将XPlaneConnect-1.3-rc6/C/src内的xplaneConnect.c和xplaneConnect.h这两个文件复制到C/C++工程目录。
- 利用xplaneConnect的openUDP函数新建一个udp通信。
- 利用xplaneConnect内的getPOSI、sendPOSI、getCTRL、sendPOSI、getDREF和sendDREF等函数与X-Plane进行数据读取或写入;利用sendCOMM可以向X-Plane发送指令(类似于快捷键)。
图1.XPlaneConnect github仓库
图2.XPlaneConnect 插件和源码下载
图3.下载后的XPlaneConnect 插件和源码
图4.XPlaneConnect 插件解压复制到xplane根目录下的/Resources/plugins/目录
图5.XPlaneConnect.c和xplaneConnect.h这两个文件复制到C/C++工程目录
代码示例
c++
#include <iostream>
#include "xplaneConnect.h"
int main(int argc, char* argv[])
{
//利用xplaneConnect自带的openUDP函数新建一个udp通信
XPCSocket client = openUDP("127.0.0.1");//"127.0.0.1"为XPlane所在电脑的ip
const int aircraftNum = 0;//X-Plane当前用户飞机为0,其他编号为AI飞机
while (1)
{
//利用getPOSI获取飞机位置、姿态和起落架状态,由于经纬度数据需要较高的数据精度,因此需要用double类型
//利用sendPOSI可以实现飞机位置、姿态和起落架状态的控制
//[Lat, Lon, Alt, Pitch, Roll, Yaw, Gear]
double posi[7];
int result = getPOSI(client, posi, aircraftNum);
if (result < 0) // Error in getPOSI
{
break;
}
//利用getCTRL获取飞机的升降舵、副翼、方向舵、油门杆、起落架、襟翼以及扰流板数据
//利用sendCTRL可以实现飞机升降舵、副翼、方向舵、油门杆、起落架、襟翼以及扰流板的控制
//[Elevator, Aileron, Rudder, Throttle, Gear, Flaps, Speed Brakes]
float ctrl[7];
result = getCTRL(client, ctrl, aircraftNum);
if (result < 0) // Error in getCTRL
{
break;
}
//设置X-Plane飞行仿真暂停/恢复
result = sendCOMM(client, "sim/operation/pause_toggle");
if (result < 0) // Error in sendCOMM
{
break;
}
//利用getDREF获取X-Plane飞行仿真是否暂停的状态
float simPaused[1] = { 0.0f }; //用于存放"sim/time/paused"的状态
int drefArraySizze = 1; //"sim/time/paused"接口的数组大小,该接口不是数组则为1
result = getDREF(client, "sim/time/paused", simPaused, &drefArraySizze);
if (result < 0) // Error in getDREF
{
break;
}
//设置X-Plane内的时间(祖鲁时间,协调世界时)
//sim/time/zulu_time_sec
float zuluTime = 9 * 60 * 60;//设置为早上9点(如果要设置本地时间,需要添加时差)
result = sendDREF(client, "sim/time/zulu_time_sec", &zuluTime, 1);
if (result < 0) // Error in sendDREF
{
break;
}
printf("Loc: (%4f, %4f, %4f) Aileron:%2f Elevator:%2f Rudder:%2f\n",
posi[0], posi[1], posi[2], ctrl[1], ctrl[0], ctrl[2]);
Sleep(100);
}
}
数组类型数据读写:
c++
//设置X-Plane各风层风向
float windDir[13] = {0.0f};
result = sendDREF(client, "sim/weather/region/wind_speed_msc", windDir, 13);
if (result < 0) // Error in sendDREF
{
break;
}
图6.数组类型数据接口示例
接口列表
X-Plane 指令列表(Command): https://siminnovations.com/xplane/command/index.php
X-Plane 数据读写接口(Datarefs): https://developer.x-plane.com/datarefs/#search-form
图7.X-Plane 指令列表
图8.X-Plane 数据读写接口