FlightGear + Jupyter + Bokeh

Streaming live data from FlightGear to plots in a Jupyter notebook

Andreas Klostermann

  • @BayesianHorse
  • www.github.com/akloster/jupyter-flightgear

Introduction

This is a demonstration of how to use the flexibility of Jupyter and Bokeh to create rich and impressive data science environments.

FlightGear is a very mature and sophisticated open source flight simulation for multiple platforms. It offers several ways to monitor the variables of the simulation, one of which is a websocket interface, which can be easily integrated into the IPython kernel framework.

In order to run this notebook you need a recent Anaconda install for Python 3.5 with Bokeh and Jupyter. You also need a resonably recent FlightGear installation (3.6 for example).

In the demonstration video I used this command line to start FlightGear:

./run_fgfs.sh --fg-aircraft=/media/internal_2/aircraft --disable-ai-models  --prop:/sim/ai-traffic/enabled=false --prop:/sim/traffic-manager/enabled=false  --disable-enhanced-lighting --disable-clouds3d --disable-clouds3d --geometry=500x500 --httpd=9095

A couple of the options have to do with optimizing for screen capture. The only important option is "--httpd=9095" which enables the internal webserver.

This notebook file can be viewed either just-as-is, with all the notes and details, or as a presentation with live-reveal.


In [ ]:
%%html
<style>
 .container.slides .celltoolbar, .container.slides .hide-in-slideshow, #exit_b, #help_b {
    display: None ! important;
}
section#slide-0-0 {
}
// Some styles to make presentation better for video capture
.container.slides {
    width: 1500px;
    
}
.container.slides .text_cell_render{
    font-size: 1.4em;
}
.container.slides .cell .input {
    font-size: 1.2em;
}
</style>

In [ ]:
# Setting up the environment
import bokeh
from bokeh.plotting import *
import bokeh_update
output_notebook()
bokeh_update.install_javascript()

from flightgear import FlightGearConnection
from attitude import AttitudeIndicator
from utils import StopButton

In [ ]:
# Run the FlightGearClient
fg = FlightGearConnection("localhost", 9095)
fg.connect()

pitch = fg.listen("/orientation/pitch-deg")
roll = fg.listen("/orientation/roll-deg")
altitude = fg.listen("/position/altitude-agl-ft")
airspeed = fg.listen("/velocities/airspeed-kt")
groundspeed = fg.listen("/velocities/groundspeed-kt")

In [ ]:
# Create Plot
attitude_indicator = AttitudeIndicator()
show(attitude_indicator.plot)

# Loop
button = StopButton(description="Stop")
@button.loop(interval=0.20)
def iterate():
    p = pitch.values[-1]
    r = roll.values[-1]
    attitude_indicator.update(p,r)

In [ ]:
from timeseries_demo import TimeSeriesDemo

In [ ]:
demo = TimeSeriesDemo()
demo.update(airspeed, groundspeed, altitude, transmit=False)
show(demo.ag_plot)
show(demo.altitude_plot)
# Loop
button = StopButton(description="Stop")
@button.loop(interval=0.5)
def iterate():
    demo.update(airspeed, groundspeed, altitude)

In [ ]: