• No results found

Källförteckning och länkar

• Lägga till hantering av TCP och onoggrannhet i datastrukturen adsb_data

för att kunna avgöra vart planen har planerat att åka, samt för att kunna bestämma ett område som ett planet kan befinna sig inom. På så sätt kan det teoretiskt minsta avståndet till omgivande plan förtydligas.

• Anpassning till AerotechTelubs befintliga rutiner för grafikritning har ej ta-

gits i beaktning vid programmets planering. Detta beroende på att koden inte varit tillgänglig av olika skäl. Risken är att denna del inte har sam- ma grundtanke om att inte låsa eller skapa för stora tidsfördröjningar som programmet i examensarbetet har.

• Mycket av databeräkningarna kan med stor fördel placeras i transponderns

program. Bland annat de delar som håller koll på alla omgivande farkosters data. Detta eftersom transpondern sedan tidigare håller koll på de tidsluc- kor som reserverats av omgivande farkoster samt beräknar den förbättrade positionen ur de mottagna dataströmmarna för de olika flygplanen. De delar som istället bör prioriteras är grafiken och interaktionen till piloterna, samt andra delar som inte direkt hör till ökad flygsäkerhet.

5.4

Källförteckning och länkar

AerotechTelub (division Sensorsystem) www.aerotechtelub.se

VDL4 Interface Protocol Skynet (00.24-5.01.doc) Sectra Wireless Technologies AB

www.sectra.se/wireless/

Diverse relevanta dokument blinder.lfv.se/ans/card/document.htm

Manual on Detailed Technical Specifications for the

VDL Mode 4 Digital Link (Appedix B, Revision to AMCP/7-WP/81) blinder.lfv.se/ans/card/docs/pdf/tm_amcp_rev2%20chv51.pdf

GP&C Systems International AB www.gpc.se

Serial Programming Guide for POSIX Operating Systems www.easysw.com/˜mike/serial/

Information om LATEX

BILAGA A

Kravspecifikation

Följande sida visar den ursprungliga kravspecifikationen så som arbetet var utfor- mat till en början. Förändringar som gjordes direkt var längden på examensarbe- tet, från 20 till 10 poäng. Detta medförde att det skulle bli vissa svårigheter att hinna med sammanfogningen mellan kommunikationsgränssittet och en befintlig programvarumodul för grafikhantering. Istället ersattes denna del med en enkel textutskrift till skärm.

Ytterligare förändringar ägde rum strax innan halva tiden, då programme- ringsspråket byttes från C++ till ANSI-C. Detta visade sig inte medföra så stora problem eftersom mycket av koden enkelt kunde omvandlas till ANSI-C. Andra delar som t.ex. klasser omvandlades till enklare datastrukturer.

Exjobb på division Sensorsystem

Titel: Programvaruutveckling för ADS-B, 20p (ref.nr. 8006) Beskrivning av examensarbetet/uppsatsen:

Bakgrund

Automatic Dependant Surveillence Broadcast (ADS-B) är en ny teknik som används för att utbyta information mellan flygplan och/eller trafik- ledningssystem. AerotechTelub utvecklar bland annat presentationssystem (dator+display) för placering i flygplan och vill komplettera befintlig programvara med programvarumoduler för ADS-B.

Uppgift

Definiera, utveckla och dokumentera programvarumodul för kommunika- tion med ADS-B transponder.

Utvecklingsmiljö: PC, Microsoft Visual C++

Programspråk: C++ med MFC

Ort för examensarbete/uppsats: Linköping

Examensarbetes/uppsatsens längd: 20 veckor

Önskat antal studenter: 1 person

Börja tidigast: 2002-05-01

Börja senast: 2002-08-01

Kontaktperson: Pedro Lundquist

Avdelning: Division Sensorsystem

Telefon: 013-23 15 95

E-post: pedro.lundquist@aerotechtelub.se

Adress: Ingen gatu/box uppgift

BILAGA B

Funktionsbeskrivning

De funktioner som programmet är uppdelat i kommer att beskrivas i denna del. Många av dem har namn som gör dem ganska självförklarande medan andra kräver en mer ingående förklaring av vad de gör. I vissa fall är också deras in och utdata av speciellt intresse. Funktionerna är grupperade till de filer som de härstammar ifrån.

B.1

main.c

int main(int argc, char *argv[])

Programmets huvudfunktion som tar kommandoraden som inparameter. Komman- doraden blir uppdelad i ord som separeras med mellanslag. char *argv[] inne- håller pekare till de textsträngar som skrevs på kommandoraden, medan int argc anger hur många strängar det finns. I denna funktion sker sammankopplingen av programmets olika delar. Det testas om det kommit något meddelande, och om så är fallet anropas den del som kan ta hand om det. Under tiden som det inte kommer in några meddelanden anropas de olika delarna ifall de har någon data som behöver uppdateras. Detta görs sedan hela tiden fram till ett meddelande om avslut kommer från transpondern.

byte subscribe_on_message(byte id_number,byte plugin_number)

Denna funktion har hand om att begära prenumeration på en specifik typ av med- delande från transpondern samt att lagra vilken insticksmodul som begärde detta. För närvarande använder bara filen ads_b.c denna funktion, men tänkbart är att filen fis_b.c och framtida insticksmoduler också kan utnyttja detta.

Praktiskt vore om denna funktion med tillhörande variabler placerades i filen vip.c. Även den del som senare fördelar alla inkommande meddelanden. Detta för att kunna förbättra ordningen i programmet och även öka prestandan och tillför- litligheten genom förbättrad hantering av inkommande meddelanden.

void exit_program(byte close_code)

För att förenkla avslutandet av programmet används denna funktion bland annat för att vid behov först avsluta uppkopplingen till transpondern innan serieporten stängs. Om programmet har prenumererat på några meddelanden, finns möjlig- heten att säga upp dem innan uppkopplingen avslutas. Den används också ifall programmet behöver startas om av någon orsak t.ex om transpondern måste star- tas om.

B.2

vip.c

word get_crc16(byte *buffert,word buffert_size)

Denna funktion beräknar en CRC16 kontrollsumma på det fältet som pekas ut av

den första parametern. Detta är en tämligen vanlig metod för att försäkra sig om att den data som skickas eller tas emot är korrekt. I paketet medföljer detta värde så att mottagaren sedan kan jämföra sitt eget framräknade värde med.

word pack_datalink(byte *in_buffert, byte *out_buffert, word buffert_size) word unpack_datalink(byte *in_buffert,

byte *out_buffert, word buffert_size)

För att överföra data med seriekommunikation kommer det uppstå ett problem. Det går inte att avgöra datapaketets början och slut. Lösningen är att använda sig av kontrolldata som flätas in i dataströmmen. Denna metod som används här kallas för byte stuffing. Det går ut på att man ersätter en byte av ett speciellt värde med två andra byte. Två stycken värden är tvungna att bytas ut. När man sedan skall ta fram den ursprungliga datan, letar man efter kombinationen av två byte, och ersätter den med det korrekta värdet. Allt detta för att reservera ett specifikt värde på en byte som används till att indikera start och stopp på paketet. Funktionerna pack_datalink och unpack_datalink konverterar dataströmmen till respektive ifrån det dataformat som överförs via serieporten. Storleken på det resulterande fältet som pekas ut av *outbuffert returneras av funktionerna.

B.2. vip.c 41

byte check_message()

När denna funktion körs, hämtas en byte i taget från serieporten. Anledningen till detta är för att kunna upptäcka stopp-byte som förklarades i föregående stycke. Om ingen data har tagits emot returnerar funktionen utan fel. När data väl tas emot, lagras den i serial_in_buffert[] fram tills en stopp-byte anländer. Då returneras ett värde för att indikera att det finns ett datapaket i inbufferten. Samtidigt som ett komplett datapaket tagits emot, hindras fler byte att hämtas från serieporten fram tills paketet har blivit omhändertaget.

Om något går fel vid överföringen kommer funktionen försöka synkronisera sig med nästa paket. Detta innebär att det går att tillfälligt koppla ur seriesladden utan att tvingas starta om alltsammans.

byte get_message(vip_data *data_ptr)

När ett nytt paket finns tillgängligt för att hämtas från serial_in_buffert[], an- ropas funktionen unpack_datalink för att packa upp paketet till pdu_buffert[].

Därefter beräknas CRC16-kontrollsumman på paketet för att avgöra om allt verkar

stämma. Hädanefter kan de pekare som angavs i kapitel 4.5 användas för att plocka ut kommando, sekvensnummer, meddelande typ m.m ur datapaketet. Dessa vär- den lagras sedan i den datastruktur som angivits som inparametern till funktionen. Om meddelandet hade tillhörande data går det att komma åt denna med pekarna adu_reply_parameter_buffert och adu_indication_parameter_buffert bero- ende på vilken typ av meddelande det var.

byte wait_on_message(vip_data *data_ptr)

Denna funktion utnyttjar funktionerna check_message och get_message. Om det har kommit ett komplett meddelande, returneras en indikering att ett paket har mottagits. Det speciella med funktionen är att den maximalt väntar 2 sekunder på att det skall anlända ett datapaket. Annars returneras en indikering på att det tagit för lång tid. Detta används för att direkt kunna använda svaret på en förfrågan till transpondern. Till skillnad mot wait_on_specific_message missar denna funktion inga datapaket. Ett sätt att komma runt problemet med upp till 2 sekunders fördröjning, är att först anropa funktionen check_message för att på så sätt snabbare avgöra om det finns något paket att hämta.

byte wait_on_specific_message(vip_data *rcv_data_ptr, vip_data *data_ptr_sent)

Beter sig på ett liknande sätt som wait_on_message, men tar en extra parame- ter. Denna innehåller en pekare till en datastruktur som i sin tur innehåller den

förfrågan som tidigare sänts och som programmet speciellt väntar på. Genom att jämföra information om det sända paketet med det mottagna, kan funktionen av- göra om det är ett svar på just den förfrågan som efterfrågas. När rätt paket har tagits emot eller om 2 sekunder har gått återvänder funktionen med antingen ok eller tidsfel.

En stor nackdel med denna funktion är att den struntar i paket som kom- mer under tiden den väntar på det rätta. Smidigt vore om denna funktion istället anropade en meddelandehanterare som tog hand om dessa mindre önskvärda pa- ket. Genom att, som tidigare nämnt, flytta in den del av programmet som sköter hanteringen av inkomna meddelanden från main.c till de övriga kommunikations- relaterade funktioner, skulle detta problem lösas på ett smidigt sätt.

byte send_message(vip_data *data_ptr)

Innan denna funktion anropas, för att skicka datapaket till transpondern, pla- ceras ett kommandot i en datastruktur tillsammans med längden på eventuell extra data som hör till kommandot. Den extra datan placeras i det fält som adu_call_parameter_buffert pekar på. När sedan funktionen anropas, plockar

den ihop ett paket av alla delar, lägger till CRC16-kontrollsumma och omvandlar

dataströmmen till det format som sedan skickas iväg via serieporten. byte open_comport(byte portnr)

Försöker att öppna angiven serieport. Inparametern portnr kan vara mellan0 och

7. Denna begränsning beror på det sätt som funktionen är implementerad på. Nor-

malt är denna begränsning inget problem eftersom det är ovanligt med fler än 4

serieportar. Dock kan det teoretiskt sätt finnas betydligt fler. byte close_comport()

Stänger den serieport som tidigare varit öppen. Om ingen port var öppen sedan tidigare returneras fel.

byte open_session()

För att kunna få data från transpondern måste en session vara öppen. Tanken med sessioner är att olika delar av programmet som har en egen session med transpon- dern enkelt skall kunna få de paket som respektive del har förfrågat. På grund av att detta inte används i denna detta program utnyttjas endast en session. Fördel- ningen av inkommande datapaket sker på andra sätt.

B.2. vip.c 43

byte close_session()

Sänder en förfrågan att avsluta den öppna sessionen till transpondern. Funktionen wait_on_specific_message används för att se att transpondern svarar. Oberoen- de om svar kommer, rensas den interna variabeln i filen vip.c som håller reda på vilket nummer på sessionen som används.

byte clear_session()

Ifall transpondern har valt att stänga sessionen med programmet, går det inte att utnyttja funktionen clear_session för att avsluta sessionen. Transpondern skulle inte ge något svar. Därför rensas bara en den interna variabel som håller koll på sessionsnumret.

byte set_transponder_time()

Denna funktion aktiveras via kommandopromten med växeln -time. Den omvand- lar datorns systemtid till det tidsformat som transpondern använder.

byte send_conf_param(doubleword channel, byte param_type, word param_id, byte param_length, byte *param)

För att göra inställningar i transpondern rörande en mängd olika saker, används denna funktion. De två första parametrarna hör ihop med den inställning som är tänkt att påverkas enligt VIP-protokollet. De tre sista parametrarna innehåller den data som behöver bifogas för att uppdatera den valda inställningen.

byte get_conf_param(doubleword channel,word param_id,byte *param) Parametrarna i denna funktion fungerar på motsvarande sätt som i funktionen send_conf_param. Enda skillnad är att den resulterande datan kommer att skri- vas till det fält som den tredje parametern pekar på.

byte get_icao_address(doubleword *data_ptr)

Skickar en förfrågan till transpondern om att läsa den unika ICAO-adressen (In-

ternational Civil Aviation Organisation) som varje transponder har. Om allt är ok

byte get_callsign(char *data_ptr)

Fungerar på liknande sätt som get_icao_address men frågar istället efter flygpla- nets anropsnamn. Sedan skrivs9 tecken (inklusive null-tecken) till den textsträng som pekaren data_ptr pekar på.

byte get_aircraft_category(byte *data_ptr)

Fungerar på liknande sätt som get_icao_address men frågar istället efter vilken kategori flygplanet tillhör. Denna byte skrivs dit pekaren data_ptr pekar.

byte get_aircraft_status(byte *data_ptr)

Lika som get_aircraft_category, men returnerar istället flygplanets status. byte store_param_config()

För att parametrarna som ändras inte skall försvinna när transpondern stängs av, kan transponderns data lagras i ett icke flyktigt minne. Denna funktion bör inte användas i onödan eftersom många av inställningarna lämpar sig bättre att temporärt ställas in under tiden systemet är påslaget.

B.3

ads_b.c

byte init_ads_b()

Används under programmets uppstart. Funktionen byte subscribe_on_message anropas för att förmå transpondern att skicka de meddelande som har med ADS-B data att göra. Hela listan med alla registrerade flygplan rensas.

byte loop_ads_b()

Under tiden som inga meddelanden kommer in från transpondern, testas alla re- gistrerade plan om dess data är aktuell. Vid varje tillfälle som ett plan i listan får ny data, registreras tidpunkten för uppdateringen. Om flygplanet åker utanför transponderns mottagningsområde, kommer uppdateringarna att upphöra. Efter

en förutbestämd tid av60 sekunder, kommer planet betraktas som ointressant och

B.3. ads_b.c 45

byte new_message_ads_b(vip_data *data_ptr)

Denna funktion reagerar för närvarande på tre olika typer av meddelanden. Egen position, egen barometrisk höjd och VDL4 data. Det VDL4 meddelande som skic- kas kan innehålla en rad typer av format t.ex. ADS-B, FIS-B, TIS-B m.fl. I detta program riktas alla typer av format till denna funktion. Detta på grund av att

meddelandenummer 0 har används (vilket motsvarar alla typer). Dock avkodas

endast meddelanden innehållande ADS-B data. ADS-B datan är i sin tur uppdela- de i en fast och en dynamisk del. Den fasta delen innehåller bland annat position och höjd angiven med en låg precision. Till detta kan den dynamiska delen inne- hålla olika typer av data som kan förbättra precisionen av positionen och höjden. Även tidsangivelser, anropsnamn och andra typer av information kan sändas. Den extra data som skicka för att förbättra positionsangivelsen är kodad med en algo- ritm kallad CPR (Compact Position Reporting). Beroende på att olika noggranna angivelser kan blandas, bör inte en mindre noggrann angivelse kunna skriva över en tidigare angivelse. Detta hanteras med en variabel i datastrukturen adsb_data som förhindrar en försämring av noggrannheten. Dock accepteras en uppdatering

om 2 tidigare uppdateringar hindras, eller då mer än30 sekunder har gått sedan

den senaste uppdateringen. Om detta är en bra metod kvarstår att utprova. int get_altitude(word balt,byte bgo)

Den höjd som skickas med VDL4 meddelandet är inte linjärt representerad. An- ledningen till detta är inte helt glasklar, men troligtvis är detta ett sätt att spara utrymme i VDL4 meddelandet. Beroende på om det precisionshöjande delen bgo har tagits emot bifogas detta. Annars sätts denna till0. Funktionen returnerar en höjd angiven i fot.

word get_ground_speed(word gs)

Även denna funktion omvandlar ett olinjärt värde. Det hastighet som skickas med VDL4 meddelandet omvandlas till en linjär hastighet.

short get_altitude_rate(word altr)

Återigen en funktion som omvandlar ett olinjärt värde till ett linjärt sådant. Denna funktion returnerar stigningshastighet för det mottagna planet. Ett positivt värde motsvarar en stigning.

void decode_callsign(doubleword csl, doubleword csr, char *callsign)

För att spara plats är den textsträng som innehåller planets anropsnamn kompri-

merad. Plats finns för 8 tecken och de tecken som är tillåtna är A-Z, 0-9 samt

Null-tecken. Sammantaget blir det36 olika tillåtna tecken som trycks ihop till 42

bitar. Normalt skulle det krävas 64 bitar. Funktionen returnerar 8 ASCII-tecken

samt ett Null-tecken.

B.4

fis_b.c

byte init_fis_b()

Denna funktion är tänkt att fungera på ett liknande sätt som init_ads_b(), för- utom att den istället begär att få prenumerera på de VDL4 meddelanden som hör ihop med TIS-B formatet. (Denna funktion är inte implementerad).

byte loop_fis_b()

Uppdaterar och kontrollerar den interna data som hör i hop med TIS-B formatet.

(Denna funktion är inte implementerad).

byte new_message_fis_b(vip_data *data_ptr)

Denna funktion är tänkt att fungera på ett liknande sätt som new_message_ads_b, förutom att den istället avkodar VDL4 meddelanden som hör ihop med TIS-B for- matet. (Denna funktion är inte implementerad).

B.5

config.c

byte configurate_vip()

Vid programmets uppstart anropas denna funktion för att göra inställningar som berör formen på kommunikationen med transpondern. Dock är dessa inställningar hårdkodade i programmet. (Denna funktion är inte implementerad).

byte configurate_transponder()

För att justera t.ex. planets anropsnamn, icao-adress och liknande ADS-B relate- rade data, anropas denna funktion. Även inställningar som har med transponderns driftfunktion kan tänkas vara placerad i denna funktion.

B.6. display.c 47

B.6

display.c

byte init_display()

Vid uppstart körs denna funktion för att bland annat justera upplösningen på skärmen. Eftersom detta program endast använder ett textläge för att visa den inkommande datan på, finns inget behov att justera inställningen för skärmen. Annars vore det lämpligt är att justera upplösningen beroende på den hårdvara som programmet körs på. (Denna funktion är inte implementerad).

byte display_loop()

Under tiden som det inte kommer in några meddelanden från transpondern, finns tid för att uppdatera skärmen. Eventuellt så har omgivande plan förändrat sin position sedan funktionen kördes senast. Denna funktion testar vilket eller vilka plan som har uppdaterats och anropar funktionen print_data med denna flygplans datastruktur.

void print_data(adsb_data *data_ptr)

BILAGA C

Kodlistning

Följande källkod är det som producerats under examensarbetet Kommunikations-

gränssnitt mot GP&C transponder. Även om programmet inte kan köras utan av-

sedd transponder eller motsvarande emuleringsprogramvara, kan bitar av koden ända vara till nytta för den intresserade. Speciellt de delar som har med seriekom- munikationen att göra, eftersom denna är skriven för att passa flera plattformar.

C.1

main.h

#ifndef MAIN_H #define MAIN_H

extern byte subscribe_on_message(byte id_number,byte plugin_number); /*byte rerun_flag*/ #define total_exit 0x0f #define exit_prg 0x01 #define unsubscribe 0x02 #define exit_session 0x04 #define exit_port 0x08 /*byte command_flag*/ #define config_mode 0x01 #define set_time_mode 0x02 #endif 49

C.2

main.c

#include "common_def.h" #include "main.h" #include "vip.h" #include "ads_b.h" #include "fis_b.h" #include "config.h" #include "display.h" #include <stdio.h> #include <string.h>

/*#include <process.h>*/ /* not neccessary to include.

dos/windows specific header-file.*/ void exit(int); /* to avoid warning.*/

byte read_message_loop(); byte set_transponder_time();

void exit_program(byte close_code);

byte rerun_flag=0; /* used when program restart, at first start->rerun_flag=0.*/ unsigned int errorcount=0; /* keep track of bad packets etc.*/ byte message_id_list[256]; /* list of active plugins corresponding

to subsription.*/ vip_data send_data, received_data;

/*--- ---start--- ---*/ int main(int argc, char *argv[])

{

byte i, result, command_flag=0; while(1)

{ /* this is only to make it possible to reboot of transponder.*/ /*CHECK COMMANDLINE*/

if(rerun_flag==0) /*if restart, flag will not be 0.*/ {

for(i=1;argv[i]!=NULL;i++) /* check commando-line.*/ {

if(strcmp(argv[i],"-config")==0) {

command_flag=(command_flag|config_mode); }

C.2. main.c 51

else if(strcmp(argv[i],"-time")==0) {

command_flag=(command_flag|set_time_mode); }

else if(strcmp(argv[i],"-help")==0 || strcmp(argv[i],"-?")==0) {

printf("help:\n-time to update time in " "transponder.\n"

Related documents