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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aircraft_typeground_speedlatitudelongitudevertical_speedheadingcurrent_flight_levelrequested_flight_levelcleared_flight_level
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aircraft_typecleared_flight_levelcurrent_flight_levelground_speedheadinglatitudelongituderequested_flight_levelvertical_speed
VJ159A34640039996.25198049.393529-0.1275400-360
VJ405B77W20020000.0013918053.573276-0.12754000
\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. ![I-sector as loaded in Twitcher](../images/twitcher_i_sector_initial.png)" + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aircraft_typecleared_flight_levelcurrent_flight_levelground_speedheadinglatitudelongituderequested_flight_levelvertical_speed
VJ159A34640039996.25198049.393529-0.1275400-360
VJ405B77W20020000.0013918053.573276-0.12754000
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aircraft_typecleared_flight_levelcurrent_flight_levelground_speedheadinglatitudelongituderequested_flight_levelvertical_speed
VJ159A34640038794.5215049.486888-0.1275400-1500
VJ405B77W20020000.016418053.505683-0.12754000
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aircraft_typecleared_flight_levelcurrent_flight_levelground_speedheadinglatitudelongituderequested_flight_levelvertical_speed
VJ405B77W4000020000.016418053.504201-0.12754000
\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 +[![Build Status](https://travis-ci.com/alan-turing-institute/dodo.svg?branch=master)](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 [![Build Status](https://travis-ci.com/project-bluebird/aviary.svg?branch=develop)](https://travis-ci.com/alan-turing-institute/aviary)