diff --git a/guides/I-sector.geojson b/guides/I-sector.geojson
new file mode 100644
index 0000000..a3b2731
--- /dev/null
+++ b/guides/I-sector.geojson
@@ -0,0 +1,257 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "geometry": {},
+ "properties": {
+ "name": "I-sector",
+ "type": "FIR",
+ "children": {
+ "SECTOR": {
+ "names": [
+ "I-sector"
+ ]
+ },
+ "ROUTE": {
+ "names": [
+ "ASCENSION",
+ "FALLEN"
+ ]
+ },
+ "FIX": {
+ "names": [
+ "SPIRT",
+ "AIR",
+ "WATER",
+ "EARTH",
+ "FIYRE"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "I-sector",
+ "type": "SECTOR",
+ "shape": "I",
+ "origin": [
+ -0.1275,
+ 51.5
+ ],
+ "children": {
+ "SECTOR_VOLUME": {
+ "names": [
+ "-2740017968558664903"
+ ]
+ },
+ "ROUTE": {
+ "names": [
+ "ASCENSION",
+ "FALLEN"
+ ]
+ }
+ }
+ },
+ "geometry": {}
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -0.2597,
+ 51.0838
+ ],
+ [
+ -0.2621,
+ 51.9161
+ ],
+ [
+ 0.0071,
+ 51.9161
+ ],
+ [
+ 0.0047,
+ 51.0838
+ ],
+ [
+ -0.2597,
+ 51.0838
+ ]
+ ]
+ ]
+ },
+ "properties": {
+ "name": "-2740017968558664903",
+ "type": "SECTOR_VOLUME",
+ "lower_limit": 140,
+ "upper_limit": 400,
+ "length_nm": 50,
+ "airway_width_nm": 10,
+ "offset_nm": 10,
+ "children": {}
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "ASCENSION",
+ "type": "ROUTE",
+ "children": {
+ "FIX": {
+ "names": [
+ "FIYRE",
+ "EARTH",
+ "WATER",
+ "AIR",
+ "SPIRT"
+ ]
+ }
+ }
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -0.1275,
+ 50.9174
+ ],
+ [
+ -0.1275,
+ 51.0838
+ ],
+ [
+ -0.1275,
+ 51.5
+ ],
+ [
+ -0.1275,
+ 51.9161
+ ],
+ [
+ -0.1275,
+ 52.0826
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "FALLEN",
+ "type": "ROUTE",
+ "children": {
+ "FIX": {
+ "names": [
+ "SPIRT",
+ "AIR",
+ "WATER",
+ "EARTH",
+ "FIYRE"
+ ]
+ }
+ }
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -0.1275,
+ 52.0826
+ ],
+ [
+ -0.1275,
+ 51.9161
+ ],
+ [
+ -0.1275,
+ 51.5
+ ],
+ [
+ -0.1275,
+ 51.0838
+ ],
+ [
+ -0.1275,
+ 50.9174
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "SPIRT",
+ "type": "FIX"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.1275,
+ 52.0826
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "AIR",
+ "type": "FIX"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.1275,
+ 51.9161
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "WATER",
+ "type": "FIX"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.1275,
+ 51.5
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "EARTH",
+ "type": "FIX"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.1275,
+ 51.0838
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "FIYRE",
+ "type": "FIX"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ -0.1275,
+ 50.9174
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/guides/digital-twin.ipynb b/guides/digital-twin.ipynb
index f00d8b4..ff2a509 100644
--- a/guides/digital-twin.ipynb
+++ b/guides/digital-twin.ipynb
@@ -1,5 +1,896 @@
{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Running an airspace simulation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This notebook is intended to run through uploading an \"I\"-shaped sector into a simulation and the basics of interacting with `BlueSky` via `pydodo`.\n",
+ "For a full overview of the `pydodo` commands, please see the [pydodo specification document](https://github.com/project-bluebird/dodo/blob/master/Specification.md).\n",
+ "\n",
+ "## Contents\n",
+ "\n",
+ "* [1. Getting started](#first-section)\n",
+ "* [2. Load sector and scenario](#second-section)\n",
+ "* [3. Example usage](#third-section)\n",
+ "* [4. Example OpenAI interface](#fourth-section)\n",
+ "* [5. Shut down the simulator](#fifth-section)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Getting started "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 1.1 Launch simulator (`BlueSky`) and the `BlueBird` interface layer\n",
+ "\n",
+ "If you have not already started the BlueSky simulator and BlueBird, you can launch them using either docker, by navigating to the [Simurgh](https://github.com/alan-turing-institute/simurgh.git) repository that contains the docker container and running..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Creating network \"guides_default\" with the default driver\n",
+ "Creating bluesky ... \n",
+ "\u001b[1BCreating bluebird ... done\u001b[0m\n",
+ "\u001b[1BCreating twitcher ... mdone\u001b[0m\n",
+ "\u001b[1Bting twitcher ... \u001b[32mdone\u001b[0m"
+ ]
+ }
+ ],
+ "source": [
+ "!docker-compose --file docker-compose.yml up --detach"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "or via the command line as outlined in the installation instructions page"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 1.2 Import pydodo\n",
+ "Pydodo will be used to communicate with the simulator"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pydodo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To check pydodo is comminicating with BlueBird:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "http://localhost:5001/api/v2\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(pydodo.bluebird_connect.get_bluebird_url())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "If this is not correct (e.g., BlueBird is in fact being run on a different host), then we can change the url by using the `pydodo.bluebird_config` function:\n",
+ "For help on pydodo type"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on function bluebird_config in module pydodo.bluebird_connect:\n",
+ "\n",
+ "bluebird_config(host='localhost', port='5001', version='v2')\n",
+ " Set BlueBird host, port and version parameters.\n",
+ " Default values are taken from the config file.\n",
+ " \n",
+ " Parameters\n",
+ " ----------\n",
+ " host : str\n",
+ " BlueBird host (e.g., 'localhost' or '0.0.0.0').\n",
+ " port : int\n",
+ " BlueBird port (e.g., 5001).\n",
+ " version : str\n",
+ " BlueBird version (e.g., 'v1' or 'v2')\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(pydodo.bluebird_config)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "At the moment there is no scenario or sector information loaded, however we can confirm that pydodo is able to report on the type, speed, position, headings and a range of other aircraft parameters by typing"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " aircraft_type | \n",
+ " ground_speed | \n",
+ " latitude | \n",
+ " longitude | \n",
+ " vertical_speed | \n",
+ " heading | \n",
+ " current_flight_level | \n",
+ " requested_flight_level | \n",
+ " cleared_flight_level | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ "Empty DataFrame\n",
+ "Columns: [aircraft_type, ground_speed, latitude, longitude, vertical_speed, heading, current_flight_level, requested_flight_level, cleared_flight_level]\n",
+ "Index: []"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.all_positions()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2. Load sector and scenario "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2.1 Overview\n",
+ "\n",
+ "To start, we need to upload a **sector** and a **scenario** (in that order). \n",
+ "\n",
+ "A sector defines the area the ATCO is controling. The scenario defines the episode: that is a sequence of aircraft whose route passes through the sector.\n",
+ "\n",
+ "You can use the [Aviary](https://github.com/alan-turing-institute/aviary/tree/develop) package to create sector and scenario files (see the README for more information and file formats).\n",
+ "\n",
+ "We can check whether a sector or a scenario has been defined already (see whether `sector_name` and `scenario_name` below are not `None`):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'dt': 0.05,\n",
+ " 'mode': 'Agent',\n",
+ " 'scenario_name': None,\n",
+ " 'scenario_time': 0.0,\n",
+ " 'sector_name': None,\n",
+ " 'seed': None,\n",
+ " 'sim_type': 'BlueSky',\n",
+ " 'speed': 1.0,\n",
+ " 'state': 'INIT',\n",
+ " 'utc_datetime': '2021-09-01 00:00:00',\n",
+ " 'aircraft_ids': []}"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.simulation_info()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Nothing has been loaded yet"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2.2 Load sector and scenario into BlueSky using BlueBird"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.upload_sector('I-sector.geojson', 'I_sector')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.upload_scenario('test-scenario.json', 'test_scenario')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can check that the sector and scenario have been read into the simulation via:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'dt': 0.05,\n",
+ " 'mode': 'Agent',\n",
+ " 'scenario_name': 'test_scenario',\n",
+ " 'scenario_time': 1.2,\n",
+ " 'sector_name': 'I_sector',\n",
+ " 'seed': None,\n",
+ " 'sim_type': 'BlueSky',\n",
+ " 'speed': 1,\n",
+ " 'state': 'RUN',\n",
+ " 'utc_datetime': '2021-09-01 00:00:01',\n",
+ " 'aircraft_ids': ['VJ159', 'VJ405']}"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.simulation_info()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " aircraft_type | \n",
+ " cleared_flight_level | \n",
+ " current_flight_level | \n",
+ " ground_speed | \n",
+ " heading | \n",
+ " latitude | \n",
+ " longitude | \n",
+ " requested_flight_level | \n",
+ " vertical_speed | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | VJ159 | \n",
+ " A346 | \n",
+ " 400 | \n",
+ " 39996.25 | \n",
+ " 198 | \n",
+ " 0 | \n",
+ " 49.393529 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " -360 | \n",
+ "
\n",
+ " \n",
+ " | VJ405 | \n",
+ " B77W | \n",
+ " 200 | \n",
+ " 20000.00 | \n",
+ " 139 | \n",
+ " 180 | \n",
+ " 53.573276 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " aircraft_type cleared_flight_level current_flight_level ground_speed \\\n",
+ "VJ159 A346 400 39996.25 198 \n",
+ "VJ405 B77W 200 20000.00 139 \n",
+ "\n",
+ " heading latitude longitude requested_flight_level vertical_speed \n",
+ "VJ159 0 49.393529 -0.1275 400 -360 \n",
+ "VJ405 180 53.573276 -0.1275 400 0 "
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.all_positions()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.3 Viewing the simulation\n",
+ "\n",
+ "You can also have a look at the sector and scenario in the simulation through Twitcher by going to http://localhost:8080.\n",
+ "\n",
+ "If the \"I\" sector was loaded the Twitcher page should look like this. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3. Example usage \n",
+ "\n",
+ "See the Dodo [Specification document](https://github.com/alan-turing-institute/dodo/blob/master/Specification.md) for a detailed overview of the supported commands.\n",
+ "\n",
+ "Below we show some of them."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.1 Query aircraft positions, again"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " aircraft_type | \n",
+ " cleared_flight_level | \n",
+ " current_flight_level | \n",
+ " ground_speed | \n",
+ " heading | \n",
+ " latitude | \n",
+ " longitude | \n",
+ " requested_flight_level | \n",
+ " vertical_speed | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | VJ159 | \n",
+ " A346 | \n",
+ " 400 | \n",
+ " 39996.25 | \n",
+ " 198 | \n",
+ " 0 | \n",
+ " 49.393529 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " -360 | \n",
+ "
\n",
+ " \n",
+ " | VJ405 | \n",
+ " B77W | \n",
+ " 200 | \n",
+ " 20000.00 | \n",
+ " 139 | \n",
+ " 180 | \n",
+ " 53.573276 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " aircraft_type cleared_flight_level current_flight_level ground_speed \\\n",
+ "VJ159 A346 400 39996.25 198 \n",
+ "VJ405 B77W 200 20000.00 139 \n",
+ "\n",
+ " heading latitude longitude requested_flight_level vertical_speed \n",
+ "VJ159 0 49.393529 -0.1275 400 -360 \n",
+ "VJ405 180 53.573276 -0.1275 400 0 "
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.all_positions()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.2 Check aircraft route"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'next_waypoint': 'FIYRE',\n",
+ " 'route_name': 'ASCENSION',\n",
+ " 'route_waypoints': ['FIYRE', 'EARTH', 'WATER', 'AIR', 'SPIRT'],\n",
+ " 'aircraft_id': 'VJ159'}"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.list_route('VJ159')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'next_waypoint': 'SPIRT',\n",
+ " 'route_name': 'FALLEN',\n",
+ " 'route_waypoints': ['SPIRT', 'AIR', 'WATER', 'EARTH', 'FIYRE'],\n",
+ " 'aircraft_id': 'VJ405'}"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.list_route('VJ405')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.3 Step through the simulation\n",
+ "\n",
+ "By default, the simulation is in a paused state. To advance it, we need to call the `simulation_step` function:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for i in range(0,50):\n",
+ " pydodo.simulation_step()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This should result in the aircraft positions changing:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " aircraft_type | \n",
+ " cleared_flight_level | \n",
+ " current_flight_level | \n",
+ " ground_speed | \n",
+ " heading | \n",
+ " latitude | \n",
+ " longitude | \n",
+ " requested_flight_level | \n",
+ " vertical_speed | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | VJ159 | \n",
+ " A346 | \n",
+ " 400 | \n",
+ " 38794.5 | \n",
+ " 215 | \n",
+ " 0 | \n",
+ " 49.486888 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " -1500 | \n",
+ "
\n",
+ " \n",
+ " | VJ405 | \n",
+ " B77W | \n",
+ " 200 | \n",
+ " 20000.0 | \n",
+ " 164 | \n",
+ " 180 | \n",
+ " 53.505683 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " aircraft_type cleared_flight_level current_flight_level ground_speed \\\n",
+ "VJ159 A346 400 38794.5 215 \n",
+ "VJ405 B77W 200 20000.0 164 \n",
+ "\n",
+ " heading latitude longitude requested_flight_level vertical_speed \n",
+ "VJ159 0 49.486888 -0.1275 400 -1500 \n",
+ "VJ405 180 53.505683 -0.1275 400 0 "
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.all_positions()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.4 Change altitude\n",
+ "\n",
+ "We can also instruct the aircraft to change their path (e.g., heading or altitude).\n",
+ "\n",
+ "Below we instruct aircraft VJ405 to start climbing. This is followed by a step through the simulation:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.change_altitude(\"VJ405\", flight_level = 400)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.simulation_step()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Checking aircraft positions now, we should see a change in the `current_flight_level` as the aircraft starts climbing: Note also the cleared flight level has increased. There may be some uncertainty in this measurement as to weather the cleared flight level is now reported in feet or as a flight level. It is something that as of Summer 2021 is being looked into"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " aircraft_type | \n",
+ " cleared_flight_level | \n",
+ " current_flight_level | \n",
+ " ground_speed | \n",
+ " heading | \n",
+ " latitude | \n",
+ " longitude | \n",
+ " requested_flight_level | \n",
+ " vertical_speed | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | VJ405 | \n",
+ " B77W | \n",
+ " 40000 | \n",
+ " 20000.0 | \n",
+ " 164 | \n",
+ " 180 | \n",
+ " 53.504201 | \n",
+ " -0.1275 | \n",
+ " 400 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " aircraft_type cleared_flight_level current_flight_level ground_speed \\\n",
+ "VJ405 B77W 40000 20000.0 164 \n",
+ "\n",
+ " heading latitude longitude requested_flight_level vertical_speed \n",
+ "VJ405 180 53.504201 -0.1275 400 0 "
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pydodo.aircraft_position(\"VJ405\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 4. Example OpenAI interface \n",
+ "This is still to do, another feature we are looking at is the logging feature which should be available for agent mode I think"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 5. Shut down the simulator "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Stopping twitcher ... \n",
+ "Stopping bluebird ... \n",
+ "Stopping bluesky ... \n",
+ "\u001b[1BRemoving twitcher ... mdone\u001b[0m\u001b[2A\u001b[2K\u001b[1A\u001b[2K\n",
+ "Removing bluebird ... \n",
+ "Removing bluesky ... \n",
+ "\u001b[1BRemoving network guides_default\u001b[2A\u001b[2K\n"
+ ]
+ }
+ ],
+ "source": [
+ "!docker-compose down"
+ ]
+ }
+ ],
"metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
"language_info": {
"codemirror_mode": {
"name": "ipython",
@@ -10,19 +901,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": 3
- },
- "orig_nbformat": 4
+ "version": "3.8.8"
+ }
},
"nbformat": 4,
- "nbformat_minor": 2,
- "cells": [
- {
- "source": [
- "# Running an airspace simulation"
- ],
- "cell_type": "markdown",
- "metadata": {}
- }
- ]
-}
\ No newline at end of file
+ "nbformat_minor": 4
+}
diff --git a/guides/docker-compose.yml b/guides/docker-compose.yml
new file mode 100644
index 0000000..17c6fa9
--- /dev/null
+++ b/guides/docker-compose.yml
@@ -0,0 +1,26 @@
+version: '3'
+
+services:
+ bluesky:
+ container_name: bluesky
+ image: turinginst/bluesky:1.4.1
+ expose:
+ - 9000
+ - 9001
+ bluebird:
+ container_name: bluebird
+ depends_on:
+ - bluesky
+ image: turinginst/bluebird:2.0.0
+ ports:
+ - 5001:5001
+ environment:
+ - BS_HOST=bluesky
+ web:
+ container_name: twitcher
+ depends_on:
+ - bluebird
+ image: turinginst/twitcher:1.0.1
+ command: http-server .
+ ports:
+ - "8080:8080"
diff --git a/guides/test-scenario.json b/guides/test-scenario.json
new file mode 100644
index 0000000..9da2a49
--- /dev/null
+++ b/guides/test-scenario.json
@@ -0,0 +1,140 @@
+{
+ "_source": "https://github.com/alan-turing-institute/aviary/blob/203d251de7ea07be7f4381efa85596d9aa5b8e45/aviary/test/conftest.py#L129",
+ "aircraft": [
+ {
+ "callsign": "VJ159",
+ "clearedFlightLevel": 400,
+ "currentFlightLevel": 400,
+ "departure": "DEP",
+ "destination": "DEST",
+ "requestedFlightLevel": 400,
+ "route": [
+ {
+ "fixName": "FIYRE",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 50.91735552314281
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "EARTH",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 51.08383154960228
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "WATER",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 51.49999999999135
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "AIR",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 51.916128869951486
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "SPIRT",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 52.08256690115545
+ ],
+ "type": "Point"
+ }
+ }
+ ],
+ "startPosition": [
+ -0.1275,
+ 49.39138473926763
+ ],
+ "startTime": "00:00:00",
+ "timedelta": 0,
+ "type": "A346"
+ },
+ {
+ "callsign": "VJ405",
+ "clearedFlightLevel": 200,
+ "currentFlightLevel": 200,
+ "departure": "DEST",
+ "destination": "DEP",
+ "requestedFlightLevel": 400,
+ "route": [
+ {
+ "fixName": "SPIRT",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 52.08256690115545
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "AIR",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 51.916128869951486
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "WATER",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 51.49999999999135
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "EARTH",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 51.08383154960228
+ ],
+ "type": "Point"
+ }
+ },
+ {
+ "fixName": "FIYRE",
+ "geometry": {
+ "coordinates": [
+ -0.1275,
+ 50.91735552314281
+ ],
+ "type": "Point"
+ }
+ }
+ ],
+ "startPosition": [
+ -0.1275,
+ 53.57478111513239
+ ],
+ "startTime": "00:00:00",
+ "timedelta": 0,
+ "type": "B77W"
+ }
+ ],
+ "startTime": "00:00:00"
+}
diff --git a/images/twitcher_i_sector_initial.png b/images/twitcher_i_sector_initial.png
new file mode 100644
index 0000000..0bdd369
Binary files /dev/null and b/images/twitcher_i_sector_initial.png differ
diff --git a/intro/about.md b/intro/about.md
index b6d9c9e..24f8bb2 100644
--- a/intro/about.md
+++ b/intro/about.md
@@ -17,6 +17,10 @@ Citation info: J. M. Hoekstra and J. Ellerbroek, [BlueSky ATC Simulator Project:
## Twitcher
[Twitcher](https://github.com/project-bluebird/twitcher) is a front-end for BlueBird for monitoring the simulation via a browser. Twitcher is built using .NET Core and Fable, then compiled to Javascript.
+## Dodo
+[](https://travis-ci.com/alan-turing-institute/dodo)
+[Dodo](https://github.com/project-bluebird/dodo) is a package that provides a scaffold for building air traffic control agents. The package us written in Python (PyDodo) and R (rdodo). For an overview of all functionality, please read the [specification](https://github.com/project-bluebird/dodo/blob/master/Specification.md) document. Commands linked to specific ATCO commands are given in the [example-usage]() page.
+
## Aviary
[](https://travis-ci.com/alan-turing-institute/aviary)