X-Plane数据交互
要用X-Plane进行二次开发,免不了需要进行参数的传递,下面我们来看看与X-Plane进行数据交互都有哪些方式。
与FSX和Flightgear基本一样,X-Plane支持插件,自然也支持通过插件进行数据交互,另外还可以通过在UI界面直接设置将数据显示在主屏上(二次开发并不需要这种方式,下面不讨论),然后还支持通过UDP通过网络进行通信。实际上主要的就这几个,有一些第三方工具实际上在这三种方式基础上做了一些开发,但有时候更好用了。如NASA通过插件做了一个代理,即NASA写了个插件直接与X-Plane通信获取数据,同时该插件还通过UDP与外部程序通信,经过定制后的通信更加方便了,不需要再考虑X-Plane原生的UDP通信方式中数据对齐的问题了。下面就一一进行介绍。
一、X-Plane原生支持的通信方式
1、通过Plugin进行数据交互
在X-Plane插件开发中提供了DataRefs API(http://www.xsquawkbox.net/xpsdk/mediawiki/DataRefs)来允许Plugin读取或者与其他X-Plane Plugin交换数据数据。
在X-Plane中数据名称是一个很长的字符串,如:sim/flightmodel/position/latitude代表其对应的latitude。X-Plane中现有的变量可以从这个表中查到http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html。
关于如何使用这个些变量具体在页面中并没有给出不过可以到下面这个页面下载最新的例程。
http://www.xsquawkbox.net/xpsdk/mediawiki/Category:Sample_Code 其中SDK 2.1 Sample Code例SDK210Tests这个例程,其中就有相关用法。如下:
- // Datarefs to get the aicraft position
- SDK210Tests_refx = XPLMFindDataRef("sim/flightmodel/position/local_x");
- SDK210Tests_refy = XPLMFindDataRef("sim/flightmodel/position/local_y");
- SDK210Tests_refz = XPLMFindDataRef("sim/flightmodel/position/local_z");
另外要实际使用的时,相应的详细说明查阅www.xsquawkbox.net/xpsdk/mediawiki/XPLMDataAccess的API文档即可。
通过X-Plane插件进行数据交互好处是容易写,无需考虑字节对齐问题。但不好的一点是,plugin代码是和X-Plane主程序一起运行的,X-Plane的每一帧都会去调用X-Plane Plugin的相关内容,一旦Plugin出错很有可能导致X-Plane崩溃,这是对要命的,要知道启动一次X-Plane需要至少3分钟,这还是配置比较高的电脑。。。。所以更好,更方便的是通过外部程序与X-Plane通信获取需要的数据。那就是下面这种方式。
2、通过UDP进行通信
不得不吐槽一下,对开发者来说,X-Plane的文档写的真是太随意,太乱了,而且很多重要的内容压根就没写。所以要找到一些文档还需要自己去搜罗,比如,X-Plane自带一个UDP通信的说明文档,在其安装目录XXXX\X-Plane 10\Instructions\Sending Data to X-Plane.rtf目录下,名字叫TXT.rtf (这个文档名也是醉了)。这个文档在我第一次通过Digital安装的时候是有的,后来用DVD装完之后居然没有。。。。不管了,反正就是这个文件,如果你没找到的话,建议随便找个论坛要一下。
该文档说明的内容主要是如何与X-Plane直接进行数据交互,其中我们主要关注的是其中UDP通信部分。这部分总结一下主要是如下内容:
1)可以通过UDP与X-Plane间收发一定结构的structs(结构体)来和X-Plane进行通信。
2)这些结构体的字节对齐方式必须符合当前Intel 64-bit X-Code alignment。也就是说如果结构体中最大的数据类型是int 或是 float 那么按照4字节对齐,如果包含double,那么按照8字节对齐。
3)通过向X-Plane发送 一种命令来进数据交互,这种命令的格式为 以\0结尾的 四字节的命令字符串加数据结构体组成,例如:“PROS”这个命令是让X-Plane以一定的频率返回一套固定的数据。
需要发送以下内容:
- "RPOS"+'\0'(null terminated )+
- struct rpos_struct_in
- {
- xint rpos_freq;//实际发送时,结构体对象中rpos_freq应该有值。
- };//(其中 “+” 不发送)
再来段原版英文解释:
So what is the 5-char message prologue? Easy! The first 4 chars are the message type, So, to send a UDP message to X-Plane, just send: |
然后,将对应的这一串数据发送到X-Plane所在计算机的49000端口上,然后X-Plane就会向外发送一组预先定义好的数据(X-Plane will send the minimum data needed to drive an external visual or moving map to the same IP address and port number you sent this message from! Easy!)
X-Plane发送回来的数据格式将是如下样式的:
- “RPOS”+'\0'(null-terminated!)+
- struct position_struct
- {
- double longitude,latitude; // double is needed for smooth data here. this is good for simple 2-d maps
- float elevation_MSL,elevation_AGL; // we have AGL so you can correct the heigh above ground for your visuals to match X-Plane, if desired
- float pitch,heading,roll; // this is for making your own visuals
- float Vx,Vy,Vz; // Vxyz are the speeds in the east, up, and south directions, in meters per second. you can use these to predict longitude, latitude, and elevation smoothly.
- float Pdeg,Qdeg,Rdeg; // P Q R are the roll, pitch, and yaw rates, in aircraft axis, in degrees per second. you can use these to predict pitch, heading, and roll smoothly.
- }
实际数据肯定不是一个结构体的定义,而是整个结构体的一个对象,我们只需要自己定义这样一个结构体,将UDP收到的数据赋给该结构体,就可以取出相应的数值。
- struct position_struct
- {
- char cmd[]={'R','P','O','S','\0'};
- double longitude,latitude; // double is needed for smooth data here. this is good for simple 2-d maps
- float elevation_MSL,elevation_AGL; // we have AGL so you can correct the heigh above ground for your visuals to match X-Plane, if desired
- float pitch,heading,roll; // this is for making your own visuals
- float Vx,Vy,Vz; // Vxyz are the speeds in the east, up, and south directions, in meters per second. you can use these to predict longitude, latitude, and elevation smoothly.
- float Pdeg,Qdeg,Rdeg; // P Q R are the roll, pitch, and yaw rates, in aircraft axis, in degrees per second. you can use these to predict pitch, heading, and roll smoothly.
- }
现在我们已经和X-Plane接上头了,它可以给我发送数据了,现在我还需要给它发送数据,或者我想得到某个确定的参数,而且不是周期性的怎么办呢?
X-Plane中还是祭出了dataref的法宝,在采用UDP通信的这种方式中称之为RREF。标题也是很屌-SEND ME ALL THE DATAREFS I WANT: RREF
对应的命令就是“RREF”
- "RREF"+‘\’+
- struct dref_struct_in
- {
- xint dref_freq ;
- xint dref_en ;
- xchr dref_string[] ;
- };
dref_freq :是X-Plane回传输数据的频率(每秒多少次)
dref_en:是一个编号,你自己定义的,因为你可能向X-Plane请求了多组参数,需要一个东西去区分开你收到的到底是哪组参数的回复。
dref_string:是希望X-Plane返回的dataref的那串string,即官方称之为冗余的一长串名称。
当你想知道的dataref数据是一个数组(如引擎推力,可能有8个引擎,需要8个引擎推力参数),只需要在参数名后面加上[xxx]指明即可。如“sim/flightmodel/engine/POINT_thrust[1]”,得到第2个引擎的推力。
之后,X-Plane向源地址发回对应的数据
- struct dref_struct_out
- {
- xint dref_en ;
- xflt dref_flt ;
- };
其中的dref_en就是之前自己定义的编号。
如果想关闭数据返回,只需要再发一次命令,只不过dref_freq设置为0即可。
好了,说完数据获取,该说说如何设置参数的值了。
通过命令“DREF”,也就是发送
- “DREF”+‘\’+
- struct dref_struct
- {
- xflt var;
- xchr dref_path[strDIM];
- };
不过要注意,这里的dref_path需要填满,DREF0+(4byte byte value)+dref_path+0+spaces 使整个消息达到509字节。
例如:
- DREF0+(4byte byte value of )+ sim/cockpit/switches/anti_ice_surf_heat_left++spaces(填充到509字节)
好了,就是这样。数据发送与接收就搞定了。
当然,基本流程其实就是这样,唯一难的是需要不停的调试UDP程序、调节struct的对齐方式。虽然这非常糟心,但一旦调好了,你会很开心。
不过通过以上过程你也可能会看到,使用UDP其实也并不是很好的一种方式,中间通信的变量太多了,而且有好多流程是冗余的,而且又没有稳定连接保证,如果在网络中稍出现抖动很容易造成接收混乱,所及这种通信方式说是UDP的,但还是只适合于在近距离本地网中使用,最好是直接通过一根网线相连接的这种方式。
二、第三方通信工具
1、GitHub上的开源项目
1)NASA的X-Plane Connect(https://github.com/nasa/XPlaneConnect)简称XPC。
NASA做了一个简化版的通过UDP和X-Plane通信的插件,通过这个插件做代理,可以实现X-Plane自带的UDP那种功能。但使用起来却简单多了。
而且语言支持C、Python、Java、MATLAB等,非常强大,你可以下载对应的代码和例程学习一下。
The X-Plane Connect (XPC) Toolbox is an open source research tool used to interact with the commercial flight simulator software X-Plane. XPC allows users to control aircraft and receive state information from aircraft simulated in X-Plane using functions written in C, C++, Java, MATLAB, or Python in real time over the network. This research tool has been used to visualize flight paths, test control algorithms, simulate an active airspace, or generate out-the-window visuals for in-house flight simulation software. Possible applications include active control of an XPlane simulation, flight visualization, recording states during a flight, or interacting with a mission over UDP.
2)Flight Simulator Panels(https://github.com/dmolin/flightSimPanels)
2、jefflewis.net的博客(http://www.jefflewis.net/XPlaneUDP_9.html)
X-Plane, UDP, and Visual Basic(http://www.jefflewis.net/XPlaneUDP.html)
用VB写的通信功能。
3、http://www.nuclearprojects.com/xplane/xplaneref.html 讲解了X-Plane UDP-Message通信的基本内容,与txt.rtf 的内容基本一样。
4、一个有意义的讨论,其中包含了一段参考代码
http://forums.x-plane.org/index.php?/forums/topic/30281-help-with-udp-packets-knowledge-please/
其他资料:
其中部分可能需要花点力气到墙的另一边去。
https://www.youtube.com/watch?v=LojOSIwPpD0
http://ardupilot.org/dev/docs/testing-with-replay.html
X-Plane数据交互的更多相关文章
- Android客户端和服务器端数据交互
网上有很多例子来演示Android客户端和服务器端数据如何实现交互不过这些例子大多比较繁杂,对于初学者来说这是不利的,现在介绍几种代码简单.逻辑清晰的交互例子,本篇博客介绍第四种: 一.服务器端: 代 ...
- 使用Jquery.AJAX方法和PHP后台数据交互小结
使用jQuery的AJAX方法和后台PHP进行数据交互,交互采用的数据格式JSON格式. 我主要小小的总结了一下,我使用AJAX方法时候遇到一些小小的问题. 第一:在传递数据的时候,传输地址注意是否正 ...
- View与Control间的数据交互
View与Control间的数据交互 1.ViewBag.Name ="Name1" 2.ViewData["VD"] = "view data&qu ...
- .net实现与excel的数据交互、导入导出
应该说,一套成熟的基于web的管理系统,与用户做好的excel表格进行数据交互是一个不可或缺的功能,毕竟,一切以方便客(jin)户(qian)为宗旨. 本人之前从事PHP的开发工作,熟悉PHP的都应该 ...
- 无废话ExtJs 入门教程二十[数据交互:AJAX]
无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...
- JSP数据交互
JSP数据交互 一.jsp中java小脚本 1.<% java代码段%> 2.<% =java表达式%>不能有分号 3.<%!成员变量和函数声明%>二.注释 1 ...
- Flex数据交互之Remoting
一 前言 Flex数据交互常用的有三种方式:WebService.HttpService以及Remoting. WebService方式已在这篇文章中给出,这篇文章主要讲解以Remoting方式进行数 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式
在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交,方便页面和服务器后端进行数据的交互处理.本文主要介绍利用Jquery处理数据交互的几种方式,包括 ...
- android实现两个activity数据交互
android如何实现两个Activity数据交互?主要是根据Intent的携带功能,intent可以携带很多信息,比如Bundle,URI甚至对象(此时要序列化,并且对象里面的成员变量如果是对象,也 ...
- AngularJs $resource 高大上的数据交互
$resource 创建一个resource对象的工厂函数,可以让你安全的和RESFUL服务端进行数据交互. 需要注入 ngResource 模块.angular-resource[.min].js ...
随机推荐
- Apache 整合 Tomcat (首先Apache 发布的是PHP项目,占用端口80,tomcat 发布的是Java 项目,占用端口8080)
情况简介: Apache 整合 Tomcat (首先Apache 发布的是PHP项目,占用端口80,tomcat 发布的是Java 项目,占用端口8080),而现在是虚拟出来两个域名(希望这两个域名都 ...
- VS2010 快速写入注释小技巧
/************************************************************************//* *//******************* ...
- js 中 json对象 与 json字符串 间相互转换
在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键 JSON字符串: var str1 = '{ " ...
- Java反射获取类和对象信息全解析
反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题. 在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了. 获取类对象 Class.f ...
- .\Obj\uCOSDemo.axf: Error: L6218E: Undefined symbol LCD_Fast_DrawPoint (refe
这个问题是 没有定义此函数 解决方法是 定义并声明一下 这个函数!!!
- Graphs and Minimum Cuts(Karger's Min-Cut Algorithm)
Graphs Two ingredients 1. vertices (nodes) v 2. edges(undirected or directed) Examples: road networ ...
- 如何优化cocos2d程序的内存使用和程序大小:第一部分_(转)
译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...
- Android 仿网易新闻v3.5:上下滑动的引导页
版权声明:本文为博主原创文章,未经博主允许不得转载. 在很多天气或者新闻的应用中,我们都能看到一些字幕滚动的效果,最简单的实现为跑马灯效果,用系统提供的属性即可实现. 复杂一些的就需要自己去用自定义控 ...
- apache不解析php文档?提示需要下载(转)
在httpd.cong中 LoadModule php5_module modules/libphp5.so #这一行php5安装的时候就已经自动添加上了 AddType application/x- ...
- 通知模式实现两个textField传值及模态视图——iOS开发
通知模式实现两个textField传值及模态视图--iOS开发 利用通知模式,实现两个不同界面的textField之间的传值,在界面二输入字符,传值到前一界面的textField. 界面的切换,这里临 ...