I don't have the cash right now to buy a plane, ArduIMU, an auto pilot, and associated hardware. So, while I'm saving for the hardware, I want to play with the various algorithms out there in a simulation environment - to gain a deeper understanding and feel for it. I want to be able to code in C, so I can use the code directly in the hardware autopilot when I reach that point.

I want to use a flight dynamics model to generate sensor inputs to the autopilot (3 axis gyro, 3 axis accelerometer, GPS - just like ArduIMU), and have the autopilot generate control surface inputs to the simulated plane in the flight dynamics model.

Phase 1: Open loop. Tuning/experimenting with the AHRS algorithm. This would not require the flight dynamics model to accept control surface input from the autopilot. I would load the simulation and fly an airplane around in some pattern. The FDM would generate and log the sensor readings and the "ground truth" pitch-roll-yaw angles. My AHRS code would read in the sensor log, compute the pitch-roll-yaw angles, and would allow me to compare it with the "ground truth" data generated by the FDM.

Phase 2: Close the loop. Use the autopilot to accept sensor inputs from the FDM, and send back control surface inputs.

Right now I'm concentrating on Phase 1. Has this been done before? I've looked around a bit and it seems that FlightGear is well suited for this type of hackery. Are these properties the ones I should use to generate the correct sensor data, emulating an ArduIMU? How can I get the values I need out of FlightGear (I read that a UDP socket is used?).

*Gyro sensors*


*ground truth data to be logged and compared with my own AHRS output*

How does everyone here test their algorithms before sending it up in the air? Anyone else run their autopilot code in a closed loop with a flight dynamics model? If not, I wouldn't mind putting in some extra effort to make this interface nice/easy-to-use so that it can be used by the community out of the box for autopilot testing.

Thanks in advance!

Views: 5996

Reply to This

Replies to This Discussion


I have been experimenting with JSBSim as a stand-alone simulation tool. I have sucessfully modeled an RC-sized aircraft and collected data, but I am still working on closing the autopilot loop. I would like to eventually add FlightGear for pretty visualization.

It can be done, I'm not sure if anyone has closed the loop using FlightGear yet.

I think I may have figured it out ... well the coarse details for now anyways. I'll post when I get home from work with what I've dug up :). FlightGear has a nice way to setup your own "protocol". You can define in an .xml file what parameters you want to output, and which ones you want to input.
I found out how to log several parameters which I need. It is really easy to do with flightgear.

1. You need to create a "generic protocol" called "myproto" (or whatever).
The nodes to record are listed in the first post. Each node goes in its own block.
2. Run flight gear from command prompt like this: fgfs --generic=file, out, 20, data.xml, myproto
This will log the specified values 20 times per second to a file called data.xml using myproto.xml as the generic protocol description.

One can also output the parameters to a socket, which can be read in real-time from another application. The generic protocol can also be used to take parameters in (to close the loop!). I will investigate this and will post when i have it working.
Have you looked at what paparazzi is doing with jsbsim (http://jsbsim.sourceforge.net/) in conjunction with flightgear?
I run my simulations right on the hardware itself. I output to the ground station and watch the plane move in relation to the waypoints. I just sit in my living room and tilt the plane to hit waypoints (while making engine noises.) I have a simple GPS emulator and I estimate turnrate, climbrate and velocity based on the IR sensors.

I also have the algorithms written in Flash, because they are easier to debug/visualize and I don't need to worry about memory types in C causing new formulas to output crazy values.

Whoa Jason, that's some hackery going on there :) . I'm sure being able to have a closed loop simulation with a proper flight dynamics model and visualization software like flight gear would make development and testing muuucchhhh easier and more accurate.
Figured out how to close the loop!

Programs can interface with FlightGear through FlightGear's property tree. Very powerful.

If you run FlightGear with the --httpd= option, it will run a webserver on http://localhost: where you can browse the property tree and refresh the current values. Alternatively, in FlightGear you can type "/", and the property tree viewer will pop up and you can view the values changing in real time. I did this to figure out the sign convention for different properties.

The property tree can be read from and written to using a "Protocol". The protocol basically defines the format in which data is exchanged. You identify the nodes in the property tree which you want to interact with, the data types, the string formatting, and voila! Attached are the input and output .xml protocol files which I used.

The data can be passed through several means, serial port, tcp, udp, etc... I chose UDP for ease.

Here is how I ran FlightGear:
fgfs --httpd=5500 --generic=socket,out,40,localhost,5000,udp,output_protocol --generic=socket,in,45,localhost,5010,udp,input_protocol

I made the input data rate faster than the output data rate, because I would rather have FlightGear waiting for a new input value (when it doesn't get a new input, the last one persists) than the input being buffered.

The --generic option allows one to specify a generic protocol, which was defined in the .xml file (attached).
--generic=socket,,, ,,,.

Attached is a .c program which I wrote to interact with the property tree and provide feedback controls to FlightGear. I've implemented simple proportional control for roll and pitch to stabilize the aircraft. Timing is driven by FlightGear. The code makes a blocking call to read UDP data. It waits until it receives a new packet, processes it, and sends a packet with control inputs back to FlightGear. Then it loops again, waiting for another packet from FlightGear. Currently, everything is hardcoded (port numbers, etc ..), but it should be trivial to make it more general purpose.

This should provide a complete framework with which to write an autopilot controller in C.
Comments please!
Have you done a search for flight gear in the blogs and discussions pages? I can't find it at the moment, but I know I've seen a tutorial around here for using flight gear to close the simulation loop.
I read all 4 parts of the Curt Olson interview, but didn't see any details on running a closed loop simulation with FlightGear, nor could I find a ready-made skeleton in .C for interfacing with FlightGear, in which I could just plug in my autopilot code in .C and start experimenting. I wanted to do it in .C, so I could just take the same exact code, and with minimal modifications compile it for a hardware autopilot and make a direct comparison. Anyways, I hope someone finds this to be useful.

Curt Olson Interview (parts 1-4)

Thanks for posting your example. I am trying to do something almost identical using FlightGear 2.0.0, but, the program hangs during "loading scenery objects" on the splash screen, unless/until I have an active control loop running. The command line interface is showing "creating 3D noise texture... DONE" when it hangs. After starting the control loop, "Initializing Nasal Electrical System" shows up and things are working, but the joystick/mouse controls are "fighting" the control loop (and losing), even if I then shut the control loop off - the simulation continues to run, but the last values put in through the generic interface continue to be used.

On the same control channels (aileron, elevator), I can successfully "dual control" between the mouse and the httpd: interface, it's just the generic input interface that seems to have the conflict issues. More version details include:

Cessna C172P
Launching via FlightGear Wizard, command line:
C:\Program Files\FlightGear\bin\Win32\fgfs.exe
--fg-root=C:\Program Files\FlightGear\data
--fg-scenery=C:\Program Files\FlightGear\data\Scenery;C:\Program Files\FlightGear\scenery;C:\Program Files\FlightGear\terrasync

Or, starting straight up from the command line, I used:

C:\Program Files\FlightGear\bin\Win32\fgfs.exe
--fg-root="C:\Program Files\FlightGear\data"

and got the same result...

Any ideas how to "de-conflict" the generic input interface? At the moment, I'm leaning toward closing the loop using the httpd:, or maybe telnet: interface (since I can see they "play nicely" with the other controls), but that seems cumbersome and ultimately slow performing.

Thanks for any help!



Update: I have switched my generic format profiles from ASCII string format to binary and the lockup on startup problems have gone away.



Yes, I want this for X-Plane & FlightGear !  You made great progress!


Would it be possible add a sim_net_config option for multiple computers sim_a=HK_GCS & APM HIL interface, sim_b=FlightGear,  sim_c=X-Plane, and sim_d= X-Plane Instructor or extra window display. 

Reply to Discussion


© 2019   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service