Thursday, January 3, 2013

Attitude Visualizer for X-Plane 9 and Linux


I built the attitude visualizer for X-Plane in 2011 as an exercise to learn how to extract real-time data from X-Plane and to control it, especially for my own hardware devices such as physical flight instruments or moving cockpit. X-Plane was made in a way that makes it easy to interface through several ways (explained a bit later). First, a video of how it works. The small plastic airplane in front of the screen follows the roll and pitch attitude of the Cessna 172 that I am flying in X-Plane, in real-time:

 


As far as hardware goes, it is a general purpose, open source microcomputer board (SUBOARD) with a PIC18F4550 processor, driving two RC servo motors. The reference position for the servos are received from the PC through USB. A plugin was written for X-Plane which acts as a go-between the microcomputer board and X-Plane.

It is quite simple to obtain data from X-Plane 9 or send data to it. This enables you to create  custom hardware or software gadgets that can be used with the program. As an example, I will show you how to read aircraft roll and pitch attitude angles from X-Plane, and send them to a custom built "Attitude Visualizer" which is a mechanical device that rolls and pitches a small, physical airplane model sitting in front of the screen, in real-time, with data streaming from the program. This is a handy device when showing a flight simulator to novices because they may have a difficult time visualizing the attitude of the plane by looking at the cockpit view. This example is on Linux (Ubuntu), however the SDK is very portable, and it is quite straightforward to compile it on other operating systems.

There are several methods to obtain data from X-Plane: Over an Ethernet connection, using data dumped to a text file, or using a plugin. The Ethernet method is great if you want to run X-Plane on several computers at once. The text file metod is good if you also want to log data.

However, if you want to build panels, instruments, or simple devices like the Attitude Visualizer explained here that run on the local computer, then the plugin is probably the most suitable method. The plugin is an extension program that is loaded into X-Plane at startup, and consists of initializer and destructor functions, and functions that are called periodically, at a time interval set by us.

To write a plugin, you must first download the X-Plane Software Development Kit (SDK) from their website. So at this point, please do that first.

Second, download and unzip the source that I wrote (from samples). The source is fairly straightforward, and consists of a few programs:

InputOutput.c: This is the main program, and you would normally only use this. It connects to X-Plane, and using the data structures defined as:
    XPLMDataRef PosnRollRef;
    XPLMDataRef PosnPitcRef;
    char PosRollDesc[40] = {"sim/flightmodel/position/phi"}; //Roll value.
    char PosPitcDesc[40] = {"sim/flightmodel/position/theta"};//Pitch value.
It selects the connection variables within X-Plane. There is no main() function because this is a plugin. The main() resides somewhere within X-Plane. The main functions are:
PLUGIN_API int XPluginStart: Called when the plugin first starts.
PLUGIN_API void XPluginStop: Called when plugin will be stopped.
PLUGIN_API int XPluginEnable: Called if you enable the plugin from within X-Plane
PLUGIN_API void XPluginDisable: Same as above but for disabling.
float InputOutputLoopCB: This is the heart of the matter. This function is called periodically to extract the data. You can then do whatever you like with the data. Here we send it to our USB device (SUBOARD that will command the servo motors to move the physical aircraft model.
int SUBII_Connect: Initializes SUBARD device.
int SUBII_Disconnect: Stops the SUBOARD device.

It is important to note that the function InputOutputLoopCB blocks X-Plane. That means, X-Plane stops while our plugin executes. That also means, if you have a program that blocks (waits for some event to happen, such as USB communications in this example), then X-Plane will wait also. What results is a simulation which will either be slow, or appear like stop motion video. To prevent that, we do the USB communication in another thread, using the "pthreads" library. It is quite simple. By using a separete thread to send the data, the function InputOutputLoopCB simply records the simulator variables to local variables, and immediately exits. Therefore there is no noticeable slow down.

The remaining two functions are specific to our hardware, and would probably be replaced by whatever hardware you may want to use:

sub2usbfunc.c
usblin.c

This is the source code. You should extract it in the SDK root directory. You can compile it using the supplied Makefile, or a simple gcc command (as shown at the top of "InputOutput.c"):

gcc -shared -Wall -D_GNU_SOURCE -o Pitch.xpl InputOutput.c -lGL -lGLU -lusb -I./ -I../SDK/CHeaders/XPLM -I../SDK/CHeaders/Widgets -I/usr/lib/include sub2usbfunc.o usblin.o #(All in one line)

This basically tells GCC to link in the OpenGL libraries (GLU and GL), libusb (for SUBOARD), include the X-Plane SDK files, and also thefunctions necessary for SUBOARD communication.

You should end up with a file named: Pitch.xpl Copy this file into the directory: 
<X-Plane home directory>/Resources/plugins/

That is it. When you next start up X-Plane, you should see your plugin loaded. As supplied, this plugin will not load up if it does not see the SUBOARD connected. However, you can easily modify the program so that it will load in any case. It is also possible to activate/deactivate the plugin from X-Plane menu.

Finally, a bit about  mechanical setup. The overall view is this:

Overview. SUBOARD at lower right, pitch and roll servos lower center, linkages and the plastic plane model at the top.

Another view with pen for size reference.
The linkage consists of a center fixed support with a ball link at the top to act as a universal joint and two pushrods with ball links at the plane side for actuation. Center support is held in place with a screw terminal from an electrical terminal barrier block (generally used in household wiring). A detail view is shown below:

Remember Futaba FP-S 148's?


Here are two shots of the upper mechanical connection. The ball link at the right is for pitch, and the one towards the left is for roll. There is about 45 degrees of travel each way for each axis.


Front lower view. Leftmost ball link for roll, middle for pitch and left for support. I used servo arm pushrod holders to connect parts rigidly together.

This gives you most of what you may need to build the attitude visualizer, except for SUBOARD firmware, and SUBOARD itself. You can build the parts of SUBOARD required for this project on a breadboard by looking at its schematic. The firmware is auite simple, and if there is sufficient interest, I can post the firmware up also.

No comments:

Post a Comment