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 [ ]: