Op 21 oktober 1978 vertrok de 20-jarige Frederick Valentich1 met zijn Cessna 1822 vanop de luchthaven van Kingeiland3 (Australië). Ongeveer 45 minuten na het opstijgen maakte hij radiocontact met de luchtverkeersleiding in Melbourne om te melden dat er zich een groot vliegtuig met vier lichten op ongeveer dezelfde hoogte bevond.
Hij zei dat het gevaarte met zeer hoge snelheid op ongeveer 1.000 voet (300 m) boven hem was gepasseerd. Hij beschreef het als "een lange vorm" met "een groen licht" en zei dat het "metaalachtig" was, alsof het "overal blonk". Daarna zei hij nog
Het lijkt alsof hij een soort spelletje met mij wil spelen. Hij vliegt twee … drie keer over mij aan snelheden die ik niet kan inschatten.
Even later meldde hij dat het object "verdwenen" was en daarna zei hij dat het terug naderde vanuit het zuidwesten. Een paar minuten later zei hij
Melbourne, dat vreemde vliegtuig hangt weer boven me. … Het is aan het zweven en het is geen vliegtuig.
De microfoon van Valentich's radio bleef daarna nog 17 seconden openstaan en in die tijdspanne hoorde luchtverkeersleider Steve Robey "metaalachtige schurende geluiden" voordat het signaal wegstierf. Er werd nooit nog een spoor van Valentich of zijn vliegtuig teruggevonden.
De OpenSky Network API4 is een RESTful5 web service6 waarmee live informatie over het luchtruim kan opgevraagd worden voor onderzoek en niet-commerciële doeleinden. De URL
https://opensky-network.org/api/states/all7
geeft een lijst van zogenaamde State Vectors8 terug in JSON formaat. Elke State Vector beschrijft de toestand van een vliegtuig (voornamelijk positie, snelheid en identiteit) op een bepaald tijdstip. We hebben dit JSON-formaat reeds omgezet naar een tekstbestand waarvan elke regel 17 velden met informatie over een vliegtuig bevat. De velden worden telkens van elkaar gescheiden door een puntkomma (;) en bevatten zelf geen puntkomma's. Zo'n tekstbestand ziet er dan bijvoorbeeld als volgt uit (airplanes.txt9):
71c293;AAR761;Republic of Korea;1544531618;1544531619;116.9663;7.2267;12192;false;247.77;215.11;0;null;12969.24;7141;false;0 ab4e94;AAL83;United States;1544531618;1544531618;-159.5829;17.6578;10972.8;false;240.14;203.21;0.33;null;11643.36;2420;false;0 4bab47;THY4BD;Turkey;1544531619;1544531619;31.7443;41.6225;11582.4;false;215.48;256.33;0;null;11369.04;1304;false;0 424317;AFL1156;United Kingdom;1544531619;1544531619;41.061;49.8635;10675.62;false;221.43;156.59;0;null;10485.12;1564;false;0 46d0ae;;Greece;1544531615;1544531615;24.1268;38.0463;2720.34;false;90.2;57.58;9.75;null;2712.72;7447;false;0 e40087;FAB6051;Brazil;1544531547;1544531556;-45.9886;-23.0904;1135.38;false;108.23;299;0.33;null;1242.06;2467;false;0 896513;FDB1KF;United Arab Emirates;1544531619;1544531619;22.9365;47.1051;11277.6;false;244.46;139.44;0;null;10965.18;6553;false;0 4691c1;AEE3BR;Greece;1544531620;1544531620;17.2443;41.3157;11285.22;false;256.7;137.52;0;null;11109.96;0117;false;0 4400b3;AUA796;Austria;1544531619;1544531619;19.2778;46.4904;10370.82;false;224.53;316.58;0;null;9997.44;4550;false;0 440080;EZY3093;Austria;1544531619;1544531619;18.3759;46.2867;10668;false;240.3;132.57;0.65;null;10347.96;4742;false;0 …
De handleiding van de OpenSky Network API bevat de volgende omschrijvingen van de 17 informatievelden.
index | property | type | description |
---|---|---|---|
0 | icao24 | string | Unique ICAO 24-bit address of the transponder in hex string representation. |
1 | callsign | string | Callsign of the vehicle (8 chars). Can be null if no callsign has been received. |
2 | origin_country | string | Country name inferred from the ICAO 24-bit address. |
3 | time_position | int | Unix timestamp (seconds) for the last position update. Can be null if no position report was received by OpenSky within the past 15s. |
4 | last_contact | int | Unix timestamp (seconds) for the last update in general. This field is updated for any new, valid message received from the transponder. |
5 | longitude | float | WGS-84 longitude in decimal degrees. Can be null. |
6 | latitude | float | WGS-84 latitude in decimal degrees. Can be null. |
7 | baro_altitude | float | Barometric altitude in meters. Can be null. |
8 | on_ground | boolean | Boolean value which indicates if the position was retrieved from a surface position report. |
9 | velocity | float | Velocity over ground in m/s. Can be null. |
10 | true_track | float | True track in decimal degrees clockwise from north (north=0°). Can be null. |
11 | vertical_rate | float | Vertical rate in m/s. A positive value indicates that the airplane is climbing, a negative value indicates that it descends. Can be null. |
12 | sensors | int[] | IDs of the receivers which contributed to this state vector. Is null if no filtering for sensor was used in the request. |
13 | geo_altitude | float | Geometric altitude in meters. Can be null. |
14 | squawk | string | The transponder code aka Squawk. Can be null. |
15 | spi | boolean | Whether flight status indicates special purpose indicator. |
16 | position_source | int | Origin of this state’s position: 0 = ADS-B, 1 = ASTERIX, 2 = MLAT |
Schrijf een bash shell script airplanes dat kan gebruikt worden om een overzicht te maken van de vliegtuigen in het luchtruim die zich het dichtst bij een gegeven punt op Aarde bevinden. Punten op Aarde worden voorgesteld aan de hand van hun coördinaten $$(\lambda, \varphi)$$, waarbij $$\lambda \in \mathbb{R}$$ de lengtegraad en $$\varphi \in \mathbb{R}$$ de breedtegraad van het punt voorstelt. De grootcirkelafstand $$d$$ tussen twee punten $$(\lambda_1, \varphi_1)$$ en $$(\lambda_2, \varphi_2)$$ op een bol met straal $$r = 6371\mbox{ km}$$ (de gemiddelde straal van de Aarde) wordt dan gegeven door de formule \[d = r \cdot \arccos(\sin(\varphi_1) \cdot \sin(\varphi_2) + \cos(\varphi_1)\cdot \cos(\varphi_2) \cdot \cos(\lambda_1 - \lambda_2))\]
Om de grootcirkelafstand te berekenen van alle vliegtuigen in een tekstbestand met State Vectors airplanes.txt10 tot een punt met gegeven coördinaten $$(\lambda, \varphi)$$ kan je gebruikmaken van het commando distance. Aan dit commando moeten twee argumenten $$\lambda, \varphi \in \mathbb{R}$$ doorgegeven worden. Het commando leest het tekstbestand met State Vectors uit stdin en schrijft het terug uit naar stdout, waarbij er achteraan een extra kolom wordt toegevoegd met de grootcirkelafstand (in kilometer, afgerond tot het dichtsbijzijnde natuurlijk getal) van het vliegtuig tot het punt met de gegeven coördinaten $$(\lambda, \varphi)$$.
$ cat airplanes.txt11 | distance 40.7128 -74.006 71c293;AAR761;Republic of Korea;…;false;0;18229 ab4e94;AAL83;United States;…;false;0;9384 4bab47;THY4BD;Turkey;…;false;0;11759 424317;AFL1156;United Kingdom;…;false;0;12813 e40087;FAB6051;Brazil;…;false;0;4349 896513;FDB1KF;United Arab Emirates;…;false;0;10790 4691c1;AEE3BR;Greece;…;false;0;10147 4400b3;AUA796;Austria;…;false;0;10381 440080;EZY3093;Austria;…;false;0;10280 461f63;FIN4KX;Finland;…;false;0;10377 …
Het shell script airplanes mag ervan uitgaan dat het commando distance12 in dezelfde directory staat, maar mag er niet van uitgaan dat die directory voorkomt in het zoekpad van de bash shell.
Aan het shell script airplanes moeten verplicht twee argumenten $$\lambda$$ en $$\varphi$$ doorgegeven worden die de coördinaat van een punt op Aarde voorstellen. Optioneel kan als derde argument ook nog de locatie van een tekstbestand doorgegeven worden met de State Vectors van vliegtuigen in het luchtruim. Als er geen derde argument wordt doorgegeven dan moet het shell script de State Vectors uitlezen van stdin. Bij het omzetten van het JSON-formaat naar het formaat waarbij de informatievelden worden gescheiden door puntkomma's, hebben we ook alle State Vectors weggelaten waarbij informatie ontbreekt (null) die nodig is voor deze opgave (de informatievelden callsign, origin_country, longitude en latitude). Het shell script mag er dus van uitgaan dat er geen ontbrekende informatie is.
Het shell script airplanes moet een overzicht uitschrijven van de vliegtuigen uit het gegeven tekstbestand die zich het dichtst bij het gegeven punt op Aarde bevinden. Elk vliegtuig staat in het overzicht op een afzonderlijke regel die het kenteken (callsign) bevat, gevolgd door een dubbelpunt (:), een spatie, de grootcirkelafstand van het vliegtuig tot het gegeven punt op Aarde (in kilometer, afgerond tot het dichtsbijzijnde natuurlijk getal), nog een spatie en de tekst km. De vliegtuigen moeten in het overzicht opgelijst worden volgens stijgende grootcirkelafstand tot het gegeven punt (afgerond) en daarna alfabetisch op kenteken.
Het shell script airplanes moet ook de volgende opties ondersteunen, waarbij aan de opties -n en -d verplicht een integer-argument moet meegegeven worden:
optie -n <int>: neem maximaal de <int> dichtste vliegtuigen op in het overzicht; als deze optie niet wordt meegegeven dan moet het overzicht niet gefilterd worden op het aantal vliegtuigen
optie -d <int>: neem enkel de vliegtuigen in het overzicht op waarvan de grootcirkelafstand tot het gegeven punt op Aarde kleiner of gelijk is aan <int>; als deze optie niet wordt meegegeven dan moet het overzicht niet gefilterd worden op grootcirkelafstand
optie -c: plaats na het kenteken (en voor het dubbelpunt) in het overzicht nog een spatie en daarna tussen ronde haakjes het land waar het vliegtuig staat ingeschreven (origin_country)
Het shell script moet voor de verwerking van de opties de flexibiliteit aan de dag leggen die gebruikelijk is bij Unix commando's: volgorde van opties speelt geen rol, opties kunnen eventueel samengenomen worden, gebruik van -- om opties en argumenten van elkaar te scheiden, …. Het shell script moet ook de volgende foutafhandeling voorzien:
als het shell script niet de gepaste opties meekrijgt (enkel ondersteuning voor de opties -c, -d en -n met een verplicht argument voor de laatste twee opties) of als er niet juist twee of drie argumenten worden doorgegeven dan moet de gepaste boodschap (zie onderstaande voorbeeldsessie) uitgeschreven worden naar stderr en moet het shell script eindigen met exit status 1
als de eerste twee argumenten $$\lambda$$ en $$\varphi$$ geen reële getallen zijn waarvoor geldt dat $$-180 \leq \lambda \leq 180$$ en $$-90 \leq \varphi \leq 90$$ dan moet de gepaste boodschap (zie onderstaande voorbeeldsessie) uitgeschreven worden naar stderr en moet het shell script eindigen met exit status 2
als er een derde argument wordt doorgegeven dat geen gewoon bestand is dat kan gelezen worden dan moet de gepaste boodschap (zie onderstaande voorbeeldsessie) uitgeschreven worden naar stderr en moet het shell script eindigen met exit status 3
Als er zich geen fouten voordoen dan moet het shell script eindigen met exit status 0.
Onderstaande voorbeeldsessie geeft aan hoe het shell script airplanes moet kunnen gebruikt worden. Hierbij gaan we ervan uit dat het tekstbestand airplanes.txt13 zich in de huidige directory bevindt.
$ airplanes 40.7128 -74.006 airplanes.txt AIJ2995: 18 km ASA1420: 30 km UAL384: 212 km FDY1052: 294 km JBU1068: 557 km SWA2170: 700 km JBU1017: 742 km FFT1693: 823 km JBU52: 862 km AAL466: 995 km ... $ airplanes -n5 40.7128 -74.006 < airplanes.txt AIJ2995: 18 km ASA1420: 30 km UAL384: 212 km FDY1052: 294 km JBU1068: 557 km $ airplanes -d500 40.7128 -74.006 < airplanes.txt AIJ2995: 18 km ASA1420: 30 km UAL384: 212 km FDY1052: 294 km $ airplanes -cn6 -d1000 40.7128 -74.006 < airplanes.txt AIJ2995 (Mexico): 18 km ASA1420 (United States): 30 km UAL384 (United States): 212 km FDY1052 (United States): 294 km JBU1068 (United States): 557 km SWA2170 (United States): 700 km $ airplanes -cn6 -d1000 40.7128 -74.006 < airplanes.txt AIJ2995 (Mexico): 18 km ASA1420 (United States): 30 km UAL384 (United States): 212 km FDY1052 (United States): 294 km JBU1068 (United States): 557 km SWA2170 (United States): 700 km $ airplanes 40.7128 < airplanes.txt Syntaxis: airplanes [-n <integer>] [-d <integer>] [-c] longitude latitude [file] $ echo $? 1 $ airplanes 40.7128 -666.006 < airplanes.txt airplanes: invalid coordinates $ echo $? 2 $ airplanes 40.7128 -74.006 unknown airplanes: cannot access 'unknown' $ echo $? 3
Muhammad Ali14 werd ooit door een stewardess gevraagd of hij zijn veiligheidsgordel wilde vastmaken. Ali antwoordde:
Superman heeft geen veiligheidsgordel nodig.
De stewardess gaf hem de volgende repliek:
Superman heeft ook geen vliegtuig nodig.