• No results found

3.4 Andra bibliotek/verktyg

5.1.3 Back-end

Systemets back-end utgör länken mellan systemets front-end och RDS. Back-end hanterar all kommunikation med RDS och sparar viktig information i en databas. Informationen i databasen används i sin tur för att besvara förfrågningar från front-end. Vid användning av systemet körs back-end på egen hårdvara separerad från front-end, som körs i klientens webbläsare. Back-end har därför betydligt större tillgång till kraftfull hårdvara, och har därför även ansvar för systemets bildbehandling.

5.1.3.1 Databas

För att utföra sina uppgifter behöver back-end ett effektivt system för att hantera den po- tentiellt stora mängd data som genereras under körning av systemet. En databas upprät- tas för detta ändamål. Databasen implementerades med databashanteraren SQLite3 (se av- snitt 3.3.2). Biblioteket SQLAlchemy (se avsnitt 3.3.3) används för att underlätta hantering- en av databasen och undvika manuell hantering av de bakomliggande tabellerna och SQL- förfrågningarna.

I databasen separeras sessioner och klienter, där sessioner är körningar av systemet på en viss plats, medan klienter är användare som ansluter till en session från en fysisk enhet. Syf- tet med denna uppdelning är att underlätta framtida utökning av systemet med stöd för flera parallella sessioner eller att flera klienter ska kunna ansluta till samma session. Sådan funk- tionalitet är dock inte del av projektgruppens arbete. Alla objekt i databasen har en relation till en session, så att man i en framtida utökning kan kontrollera vilken information som ska göras tillgänglig för vilka användare. Sessionerna lagrar start- och eventuell sluttid för ses- sionen, samt vilket drönarläge sessionen som helhet för närvarande befinner sig i. För varje session sparas även det avgränsade område inom vilket drönarna får röra sig som definie- rades av användaren vid uppstart. Eftersom detta område består av en enkel polygon med godtyckligt antal hörnpunkter behöver dessa lagras i en separat tabell. För klienter sparas information om vilket område användaren för närvarande visas.

Utöver sessioner och klienter sparas information om de bilder som tagits emot från RDS. Informationen inkluderar tidpunkt då bilden togs, bildens dimensioner och koordinater. Själ- va bilden sparas på en separat fil i back-endserverns filsystem, och filnamnet sparas i data- basen. Slutligen sparas även bildens typ, det vill säga om den är tagen med en RGB- eller IR-kamera.

Användaren av systemet kan begära att en prioriterad bild skulle tas över ett område. Sådana förfrågningar sparas i databasen tillsammans med tidpunkt för förfrågan, förväntad leveranstid, status på förfrågan (pågående, avbruten eller levererad) och eventuellt id för den bild som levererats som svar på förfrågan.

För att back-end ska kunna skicka information om aktiva drönare till front-end utan att vänta på svar från RDS förhämtas denna information löpande och sparas i databasen. Infor- mationen inkluderar namn på aktiva drönare och förväntad återstående batteritid.

Testning av systemet kräver att en testmiljö för databasen kan upprättas, så att tester kan genomföras utan att deras transaktioner sparas i produktionsdatabasen. För detta ändamål finns en global inställning som styr mot vilken databasfil transaktionerna arbetar. I produk- tionsläget görs transaktioner mot den riktiga databasfilen, medan transaktioner i testläget går till en testdatabas. Testdatabasen sparas antingen i datorns minne eller på en testdatabasfil som återställs inför varje test.

5.1. Systembeskrivning

Flera separata trådar i systemet interagerar parallellt med databasen, och det är därför viktigt att databasen synkroniseras på lämpligt sätt. SQLite3 är en filbaserad databashantera- re, och stödjer därför endast att en instans av databashanteraren är ansluten till filen vid varje tillfälle. [23] Flera transaktioner kan dock vara aktiva mot samma databashanterare parallellt. För att hantera detta används scoped sessions i SQLAlchemy. Dessa lagrar information lokalt för varje tråd och kan inte delas mellan trådar. [52] När transaktionen är klar lämnas ses- sionen tillbaka till databashanterarens anslutningspool. Detta åstadkoms genom en context manager i Python, vilket minimerar risken för att sessionerna hanteras felaktigt.

Alla aktiva transaktioner måste avslutas innan bytet mellan testdatabaser och produk- tiondatabasen kan genomföras. Detta är en variant av Readers-Writers Problem, ett generellt synkroniseringsproblem som ofta uppstår då flera trådar använder en gemensam resurs [53]. Problemet löstes med en först in, först ut-algoritm, där alla aktiva transaktioner tillåts arbeta klart innan ett databasbyte kan genomföras, men inga nya transaktioner får öppnas förrän ett pågående byte har slutförts. Lösningen implementerades med synkroniseringsprimitiver från Pythons inbyggda threading-bibliotek [54].

5.1.3.2 Överföring av bilder

Under körning begär front-end kontinuerligt bilder från back-end. Detta görs genom att front-end kallar på API-anropet request_view genom Socket.IO. Detta API-anrop innehåller bland annat information om vilket område front-end vill ha bilder från. När back-end tar emot en sådan begäran hämtas alla bilder som finns lagrade i databasen, bilder som inte överlappar med det begärda området filtreras bort, och de kvarstående bilderna rekommen- deras till front-end. Back-end sammanställer metadata och en webbadress där bilden kan hämtas för varje bild som valts ut. När all information har sammanställts skickas denna till front-end via Socket.IO.

För att få tillgång till bilderna gör front-end en HTTP-förfrågan. I en bilds URL anges en unik identifierare till bilden, som används av back-end för att hitta bilden i databasen. När back-end tar emot en sådan HTTP-förfrågan skickas bilden i råformat till front-end med hjälp av funktionen Flask.send_file [55]. Är bilden inte tillgänglig skickas istället ”404 – Not Found” som felmeddelande.

5.1.3.3 Bildbehandling

Tillsammans med flygfoton levererar RDS även koordinaterna för bildens hörn och mitt- punkt. Kunden gjorde dock klart att dessa koordinater inte var helt tillförlitliga, till följd av osäkerheter i drönarnas sensorer och möjliga förvrängningar av bilden. För att flygfoto- na bättre ska stämma överens med kartbilden måste bilderna därför behandlas så att bättre koordinater kan beräknas. När koordinaterna beräknats sparas dessa koordinater, inte koor- dinaterna från RDS, i systemets databas och används sedan när bilden ska placeras på rätt plats i användargränssnittet. För en utförlig beskrivning av hur bildbehandlingen går till, se appendix D.

5.1.4

Kommunikation

I detta avsnitt beskrivs kommunikationen mellan systemets olika delar.

5.1.4.1 Kommunikation mellan RDS och back-end

Kommunikationen sker via ZeroMQ (se appendix K). Denna kommunikation sker genom tre länkar som kallas POI, PIC och INFO. Länkarna används till följande kommunikation:

• POI-länk: Används för att skicka den vy klienten för närvarande tittar på (svaret kom- mer inte direkt).

5.1. Systembeskrivning

• INFO-länk: Används för att hämta information från RDS (svaret kommer direkt). Tre separata trådar implementerades i back-end för att sköta dessa länkar. Trådarna består av en publiceringstråd, en prenumerationstråd och en informationshämtningstråd. Publice- ringstråden använder POI-länken för att skicka förfrågningar om vyer som back-end är i behov av. Tråden hanterar även andra förfrågningar som kan vara användbara för RDS att veta om, till exempel definition av område som RDS ska köra inom med drönarna. Prenume- rationstråden prenumererar på RDS och väntar på att begärda vyer ska anlända. När en vy med tillhörande flygfoto anländer anpassas bildens koordinater till kartan. Därefter sparas bilden med de korrigerade koordinaterna i databasen och front-end notifieras att en ny bild är redo för hämtning. Informationshämtartråden hämtar information regelbundet från RDS och lagrar informationen i databasen. Detta inkluderar information om alla drönare som är verksamma i det specificerade området och hur lång tid det är kvar tills nästa bild kommer skickas från RDS.

För att använda resurser på ett effektivt sätt är det viktigt att trådarna inte använda busy- waiting när de inte har något uppdrag att genomföra, till exempel när publiceringstråden inte har några förfrågningar att skicka till RDS. För att åstadkomma detta används Event-objekt från Pythons threading-bibliotek [54]. Detta gör det möjligt för trådarna att lämna ifrån sig systemresurserna när de inte längre utför något aktivt arbete.

5.1.4.2 Kommunikation mellan back-end och front-end

Tre kommunikationslänkar finns mellan front- och back-end, en huvudsaklig och två stöd- jande.

Systemets huvudsakliga kommunikationslänk (mellan front- och back-end) tillhanda-

hålls av Socket.IO (se avsnitt 3.4.7). Här hanteras all kommunikation som inte kräver spe- cifika protokoll eller dataformatering. Denna kommunikation utförs efter ett egendefinierat API (se appendix L). Genom denna länk uppdateras bland annat back-end om vilken posi- tion på kartan användaren tittar på, och front-end får information om vilka bilder som ska placeras på kartan. Genom denna länk skickas alltså all den information back-end behöver för att göra sitt arbete. Den huvudsakliga kommunikationslänken delas även logiskt upp i två underlänkar, downstream och upstream. På downstream skickar front-end förfrågningar och back-end svar, medan på upstream skickar back-end förfrågningar och front-end svar.

Systemets två stödjande kommunikationslänkar är den där flygfotona hämtas och den

där kartinformationen hämtas. Flygfotona hämtas till front-end via HTTP GET-förfrågningar på en URL som tillhandahålls av back-end. Denna URL ges av back-end via den huvudsakli- ga kommunikationslänken då front-end frågar back-end om rekommenderade bilder för en viss vy, men själva bilddatan skickas alltså via en annan länk. Detsamma gäller kartinforma- tionen som tillhandahålls av back-ends tileserver.

5.1.4.3 Kommunikation med tileservern

Kommunikation med tileservern (se avsnitt 3.4.10) sker varje gång en ny bild behandlas. När back-end tar emot en ny bild med tillhörande koordinater hämtas en bild av kartan som täcker området på bilden från tileservern. Med hjälp av bildens koordinater hämtas index för de tiles som innehåller bildens fyra hörnkoordinater. Sedan hämtas alla tiles mellan dessa hörn från tileservern var för sig som sedan sätts ihop och bildar kartan. Denna karta används sedan för att justera inkommande bilders koordinater.

Related documents