Reaalaja videotöötluse jõudluse parendamine Eesti Infotehnoloogia Kolledži Robootikaklubi Botmaster platvormi baasil
Enhancement of Real-time Video Processing Performance based on Estonian Information Technology College Robotics Club Botmaster Platform

Thursday, July 11, 2013

Chapter 5 - Veni, vidi, vici

Lõputöö kirjutamisega seotud blogis peaks varem või hiljem jõudma kätte mingi loogiline lõpp. Eks see oleneb sellest kui kähku õnnestub asjaga ühele poole saada. Mul kulus 0-100% diplomitöö valmimisele 9,5 kuud, millest enamuse ajast veetsin Rootsis. Ja seal oli kirjutamiseks väga hea keskkond - vähe segavaid faktoreid ning palju tarkust õhus. Aktiivselt tegelesin asjaga kokku umbes 4-5 kuud, millest väga-väga aktiivselt umbes kolm :)

Ühes Stockholmi tuntumaimas ärihoones, kus pesitsevad sellised IT tegijad nagu Electronic Arts või Dice, öösiti läheb päris pimedaks. Kuid mitte kuuendal korrusel, kus ma viimase 1.5 kuuga enne lõpetamist genereerisin valmis ~35lk oma tööst.
Loojang või tõus? Need kevadised ööd on väga kenad. Silm puhkab, mõte lendab.
Vahel harva kirjutasin kodus ka, tavaliselt nädalavahetustel.
Lõputöö sai kaitstud, ülikool lõpetatud ning tänasest olen ametlikult TTÜ Computer and Systems Engineering M.Sc tudeng. Tundub lahe eriala, kus tavapäraste mainstream klikitavate süsteemide asemel saab progeda põnevaid käegakatsutavaid asju.

Diplomitöö tulemusega jäin rahule. Suurepärane hinnang tuli juhendajalt, retsensendilt ning ka final komijonilt. 5 it is. Pärast kaitsmist valiti kevadiste IT-arenduse diplomitööde seast kaks päeva parimat lõputööd. Jagasin seda meeldivat tiitlit Andres Käveriga, kelle teemaks oli "Mootorsõiduki parameetrite reaalajaline monitooring ja juhtimine". Väga põnev ja tugev diplomitöö mehel.
Ülikooli lõpuaktusel sain väljapaistva diplomitöö eest veel stipendiumi Tallinna linnalt. Täispakett. Nagu ütles üks võidukas mees: "veni, vidi, vici" ;)

Blogist nii palju, et kohe, kui läks lõputöö reaalseks kirjutamiseks, siis sain üsna kähku aru, et edaspidine blogi pidamine on täiesti mõttetu. Samas see oli hea warm-up ning mõningatest märkmetest oli kirjutamisel tõesti kasu. Blogis oli 9-kuuline paus - vahepeal toimus palju põnevat, nt 3. koht Robotexil. Lõputöö kirjutamise protsess ise kannatas kord rohkem, kord vähem ja mitmel erineval põhjusel - remondi tegemine, lumelaua hooaeg jms. Ma polnud thesisega üldse rahul ning otsustasingi tegeleda asjaga usinamalt ja kauem ning lükkasin kaitsmise kevadesse. Kokkuvõttes tuli keskmisest pikem, 71-leheküljeline baka thesis.

Et postitusel oleks midagi kasulikku ka tulevastele põlvedele --> asjad, mis õppisin lõputöö kirjutamisel:
  • Teema valik - kui pole nolifer ning pole väga palju üleliigset aega, siis soovitaks võtta mõni teema, mis on seotud tööalase tegevusega (või siis mõne hobiga). Väga keeruline on pärast tihedat tööpäeva põhjalikult keskenduda täiesti teistele asjadele. Ma valisin teema, mis on seotud hobiga (progemisega robootikaklubis) ja ikka oli päris raske.
  • Juhendaja valik - oleks hea leida juhendaja, kes on teie teemast ise ka huvitatud. Mul oli lihtne - juhendajaks oli Valdur, kellega olen teinud koostööd mitu aastat ning, kellelt pärinebki suur osa minu masinnägemisega seotud teadmistest.
  • Quality Assurance - leidke omale tark naine (works better), kes loeks hea meelega lõputöö läbi ning otsiks tekstist vigu. Oma näpukaid on tõesti väga raske märgata. Mul oli abiks tubli Sandra, kes on igapäevaselt ameti poolest Quality Lead ning pädevuses ei tasunud kahelda - kaks korda luges ning mõlemal korral sain põhjaliku bugiraporti :D
  • Aeg - asjade kirjapanemine võtab oluliselt rohkem aega kui võib esmapilgul arvata. Koostage eesmärkide sooritamise plaan ning ajaline prognoos, seejärel korrutage läbi kõik kolmega.
Mitmed inimesed on avaldanud soovi mu teemaga lähemalt tutvuda. Loodan, et ootused pole liiga kõrged ja keegi ei pea pettuma, baka ikkagi :P

Thesise reliis on siin: Erik Kaju Diplomitöö @ Scribd. [Kui ei avane, siis SIIN (Google Drive)]

Monday, October 8, 2012

Chapter 4 - Things are getting serious

NEVE@Robotex
XIMEA tehasest tuli kauaoodatud uudis - meid (Robotexi team NEVE) toetatakse Currera R kaameraga. Tegemist on väga "püssi" industriaalseadmega, mida kutsutakse smartcamera'ks, ehk siis "nutikaamera".
Objektiivid on eraldi ja vahetatavad.

Nii palju tarkust on:
CPU: Intel Atom Z530 1.6GHz
RAM: 1GB
SSD mälu 3.6 GB + Micro SD võimalus
Global Shutter 5Mpix sensor


Ta on umbes nagu Audi R8 V10, aga kaamerate seas :P
Ja sellise mänguasja lisandumine kindlasti mõjutab ka minu lõputööd.




VisionTime
Vahepeal uuendasin oma pilditöötluse jõudluse mõõtmisvahendit VisionTime'i, millest rääkisin eelmises postituses. Uuendused seisnevad selles, et nüüd salvestatakse vahetulemused RAMi, mitte csv faili. Kuna mälu on peaaegu, et piiramatu, siis on see palju parem lähenemine. Ühe protsessi mõõtmine VisionTime'iga võtab nüüd ise 2000ns ehk mõõta saaks 500000 korda sekundis.
Kuna valmiv Botmasteri lahendus tuleb mitmevooline, siis tegin jõudluse mõõtja ka threadsafe'iks, Qt vahenditest sobis hästi QMutex.
VisionTime v1.2:

Thesis
Septembris pidin täitma "Lõputöö teema kavandi", seega oli viimane aeg sõnastada lõputöö lõplik pealkiri. See oli paras peavalu, sest järsku avastasin, et pean enne kirjutamist teadma päris detailselt, milliseks lõputöö siis lõpuks kujuneb. Hankisin kolme varasema lõpetaja teema kavandid, et saada üldse aimu selle dokumendi eeldatavast sisust. Palju abi oli juhendajast Valdurist, kes aitas sõnastamisel. Riputasin selle tulevaste põlvede abistamiseks ka üles.

Lõputöö pealkiriReaalaja videotöötluse jõudluse parendamine EIK Robootikaklubi "Botmaster" platvormi baasil
Ingliskeelne lõputöö pealkiriEnhancement of real-time video processing performance based on EIK robotics club "Botmaster" platform

Nüüd siis olen alustanud lõputöö enda kirjutamisega. Hetkel on käsil peatükid "Videotöötlus ning selle alamprotsessid" ja "Analüüs esialgse platvormi videotöötluse komponendi jõudlusele". Hetkel tunnen ja mõistan igat pisemat protsessi Botmasteri masinnägemise elutsükklis, sellest kirjutangi.

Pean tunnistama, et mul on väga vedanud juhendajaga. Olen jätkuvalt Rootsis ning pole vahepeal  Eestis käinud, kuid vaatamata sellele oleme Valduriga pidevalt suhelnud Skype'i ning TeamViewer'i vahendusel ning tema pädevus ja pühendumine on väga inspireeriv.

Wednesday, September 19, 2012

Chapter 3 - little smarty singleton


Tööl olid vahepeal karmid ajad, olime graafikust maas ja töötasime 10h päevas. Rootsis asjad ilmselt käivadki  nii - ühel hommikusel miitingul lihtsalt öeldi, et koodivabrik hakkab täispööretel tööle.. ja nii ongi :D Ja see kestis üle kahe nädala järjest ning oli isegi päris fun, aga lõputöö ja botmasteriga tegelemiseks ei jäänud eriti aega. Nüüd on kiired ajad jälle möödas :)

Seoses lõputöö administratiivse poolega.
  • Lõputöö deklareerisin ÕISis ära (Ei maganudki maha). 
  • Juhendaja andis ametliku kinnituse, et nõustub juhendama mu diplomitööd. Juhendajaks Valdur Kaldvee!

Vahepeal kohendasin veidi ja kompileerisin uuesti ov534 kaamera draiveri, sest esimesel korral olin teinud näpuka ja punane led tuluke läks videopildi edastamisel põlema, kuid ei kustunud enam. (Kui kaamera USBist välja tõmmata, siis muidugi kustus) Ja see pisiasi häiris.

VisionTime.cpp & VisionTime.h in Botmasters NOW!

Olemus ja Ehitus
Sain valmis oma fancy tööriista, mille disainisin antud olukorras spetsiaalselt videotöötluse jõudluse mõõtmiseks. Samas saab seda kasutada kõikjal, kus protsesside täidesaatmine toimub tsükliliselt. Panin sellele nimeks VisionTime.
Tool ise on singleton disainimustriga, mis sarnaste lahenduste puhul üldlevinud:
  • Klassi kuuluva(te) objekti(de) arv on alati rangelt piiratud ühele & alati ainult üks ligipääsupunkt
  • "Global point of access" - globaalselt ligipääsetav 
  • “Just-in-time initialization”
Ja selle saavutamiseks on kasutusel privaatne konstruktor ning privaatne pointer staatilisele objekti instantsile. (Java kutina on mul C++'is pidev peavalu nende pointeritega, no ei oska kunagi otsustada, kas kasutada või mitte :P) Instantsi "getter" on avalik ning esimasel väljakutsumisel algul loob objekti ja siis tagastab, järgnevatel kordadel lihtsalt tagastab olemasoleva. 
Paljud loggerid on taolise ülesehitusega.  Väga lihtne ja basic ning teatud funktsionaalsuse puhul ka päris vajalik. Näiteks andmebaasisessioonide puhul, kui on vaja vältida paralleelseid ühendusi.  Mul on olnud kokkupuuteid singletoniga küll, javas ka levinud, kuid üldiselt reeglina ei soovitata andmeid ja objekte kasutada globaalse kehtivusega. Aga hetkel see vastas nõudmistele ideaalselt.

Alustasin tegelikult sellega, et mõtlesin täiustada Timer.cpp klassi, mille Silver oli kirjutanud 2010 aastal oma lõputöö arvutuste jaoks. Mingi hetk sain aru, et minu tool-i funktsionaalsus hakkab vanast timer.cpp skoobist väga kaugele eemalduma. Otsustasingi teha eraldiseisvaks. Vanast timerist on kasutusel vaid samasugune ajahetke "püüdmise" printsiip.

Kuidas töötab
Koodis pannakse lipukesed enne ja pärast mõõdetavaid protsesse. Samuti seadistatakse paika, mitmendast kaadrist alates algab mõõtmine ning, mitu järjestikust kaadrit arvestatakse. 
Sel hetkel kui toimub videotöötlus, VisionTime ise mingeid kalkulatsioone ei tee, vaid salvestab Time Stamp Counter väärtusi eraldi csv faili  - (edit: järgmises versioonis loobusin csv faili kirjutamisest ning hakkasin salvestama otse RAMi, sest see on muidugi veelgi kiirem) üritab olla botmasteri videotöötlemise ajal nii lightweight kui võimalik. Väärtuste hankimiseks kasutatakse POSIX programmiliidese funktsiooni clock_gettime määrates ära parameetrina monotoonse kella (CLOCK_MONOTONIC). See loendur on nanosekundilise täpsusega ja üliväikese üldkuluga - võtab mõned protsessori taktid, et loenduri väärtus lugeda.

1 nanosekund on 1/1000000000 sekundit ehk äärmiselt väike sekundi murdosa.
Näiteks 3.3 nanosekundiga liigub valgus vaakumis kõigest ühe meetri. (vees ja atmosfääris veel aeglasemalt)

Kaks VisionTime Tool'i ajasalvestust (sündmuse algus ja lõpp) võtavad aega umbes ~50000ns(edit: 2000ns), ehk on võimelised salvestama 20 000 (edit: 500000) korda sekundis.

Kogu tulemuste arvutamine toimub alles lõpufaasis, kui on kogutud ajasalvestused soovitud arvu kaadrite kohta. Põhimõtteliselt tehakse ära "tagantjärgi arvutamine". VisionTime teeb tuhandeid arvutusi, rehkendab iga mõõdetava protsessi keskmised ja lisatab muud statistikat, mida saadud numbrite alusel saab kokku panna.

Pärast seda läheb automaatselt käima Open-Office Calc, mis kuvab tabeli koos tulemustega. (Mu lemmik featuur :D)

Umbes sellise tabeli annab välja:
(hetkel mõõdetud suht suvalised protsessid)

<... umbes 600 sarnast rida nagu järgmised kolm>
procfunc_goalB e 183564720
procfunc e 183707475
frame e 193506229




-------------------------------------------


MEASUREMENT OVERVIEW


Started_measuring_from_frame: 90

Measured_nr_of_frames: 30





-----


RESULTS


Process Total_Nanoseconds Occurrences Avg_nanoseconds
fps_calc 4345991 30 144866
Gauss 227982470 30 7599415
Lut 368607550 30 12286918
procfunct_cvline 1410093 30 47003
procfunc_goalB 185440320 30 6181344
frame 1705898552 30 56863285
procfunct_stor_crt 1106627 30 36887
procfunc_goalY 116735493 30 3891183
procfunc_ball 70547238 30 2351574
procfunc 389610809 30 12987026




-----


ACCORDING_TO_CALCULATIONS


Average_FPS: 17

Slowest_process:(procfunc) 12987026 ns (Avg.)
Fastest_process:(fps_calc) 144866 ns (Avg.)

DEMO!

Väikeses aknas captionid ei tööta päris nii nagu vaja :P


Kuidas saab panna tööle
Iseenesest mõistetav, et..
#include "visiontime.h"
VisionTime liidese juhtimine käib kujul VisionTime::DO()->funktsiooniNimi(Parameeter);
Kokku on 6 avalikku juhtimisfunktsiooni.

Esimesed kolm on mõistlik käivitada testitava programmi(nt Botmasteri) main() funktsioonis.

1. turnOn() funktsioon lülitab sisse VisionTime'i. Kui see välja kommenteerida, siis ülejäänud VisionTime'i funktsioonid ei tee mitte midagi (pole lõplikult valmis):
VisionTime::DO()->turnOn();
2. setMeasureNumberOfFrames() - määrab mitme kaadri kohta tulemused arvutatakse. Nimelt ei ole pilditöötluse kiirus konstantne, see muutub ajas pidevalt. Ühe ainsa kaadri mõõtmine on mõttetu, sest tegu võib olla kaadriga, tegelikust keskmisest parem/halvem. VisionTime kogub info etteantud arvu kaadrite kohta ning arvutab keskmised.
VisionTime::DO()->setMeasureNumberOfFrames(30);
3. setMeasutingFromFrame() - määrab mitmendast kaadrist alates alustatakse mõõtmist. Jällegi pilditöötluse kiirus pole konstante ja kaamera videovoo edastamise alguses on jõudlus mõnevõrra kehvem ning paari sekundi pärast stabiliseerub.
VisionTime::DO()->setStartMeasuringFromFrame(90);
Järgmised kolm lähevad sinna, kus toimub mõõdetav töötlemistsükkel.

4. newFrame() - lipuke, mis määrab momendi, mil algab uus kaader. Ehk siis selline rida tuleb panna koodis uue kaadri funktsiooni vahetusse lähedusse.
VisionTime::DO()->newFrame();
5. markBegin() - lipuke, mis määrab momendi, mil algab üks mõõdetavatest protsessidest. Funktsiooni argumendiks on protsessi nimetus või lühend - seda kasutatakse lõpus tulemuste kokkuvõttes.
VisionTime::DO()->markBegin("Lut");
// Mõõdetav protsess nt 'Lut' vms
6. markEnd() - lipuke, mis määrab momendi, mil lõpeb üks mõõdetavatest protsessidest. Argument on sama nagu oli protsessi alguse lipukese puhul.
VisionTime::DO()->markEnd("Lut");

VisionTime aktsepteerib ka "alamprotsesse":
VisionTime::DO()->markBegin("Process");
VisionTime::DO()->markBegin("Sub-process1");
//alamprotsess1
VisionTime::DO()->markEnd("Sub-process1"); 
VisionTime::DO()->markBegin("Sub-process2");
//alamprotsess2
VisionTime::DO()->markEnd("Sub-process2"); 
//miskit muud
VisionTime::DO()->markEnd("Process");
Kuid alamprotsess ei tohi olla sama nimega:
VisionTime::DO()->markBegin("Nimi");
//mingi protsess
VisionTime::DO()->markBegin("Nimi");
//mõõdetav protsess
VisionTime::DO()->markEnd("Nimi"); //Kumb lõpeb?
VisionTime::DO()->markEnd("Nimi"); //Kumb lõpeb?

Samuti ei pea mõõdetavad protsessid esinema sama arv kordi. Iga protsessi keskmine arvutatakse täpselt selle järgi kui tihti selle käivitamiseni programm jõudis. Ainus nõue on see, et viimase mõõdetava kaadri lõpuks ei tohi olla ühtegi pooleliolevat protsessi. Videotöötluse puhul on see loomulik, sest uue kaadri alguses peab olema kogu eelmise kaadri töötlemine juba "kauge minevik" :)

Mõned issued veel on (seoses turnOn() funktsionaalsuse ja käskude kujuga), mida tahaks muuta, aga põhiline funktsionaalsus on sellel tükil valmis. Hea mini-projektike c++'ga harjumiseks enne suuremaid vägitegusid ning lähitulevikus see jupp kannab ka vilja kuna säästab kindlasti palju aega. Igasuguse koodimuudatuse peale saab asja lihtsalt käima lükata ning vähem kui minuti pärast on ees kena tabel väljaarvutatud tulemustega. Ning kohe saab võrrelda, kuidas muudatused mõjutasid jõudlust. Elu on päris lill, kui keegi teeb alati sinu eest tülika mõõtmistöö :)

Source v1.0:
visiontime.cpp


Nüüd saan keskenduda mõõtmiste analüüsile ning alustan suurte Botmasteri uuendustöödega.

Sunday, August 26, 2012

Chapter 2 - Relocation


Mõned tuttavad techied küsisid juba, kas olen lõputöö pooleli jätnud - ei, kindlasti pole.
Lihtsalt ei saa ju postitust teha, kui pole millestki rääkida.

Noore inimese elu võib muutuda üsna ettearvamatult ja kiiresti, nii juhtus nüüd minugagi. Kolisin kohvritäie riietega teisele poole Läänemerd, Stockholmi. Töötan siin Tallinna Knowiti emafirmas, Knowit Net Resultis, ning progen koos kohalikega vinges J2EE projektis, kus ehitame ühele Rootsi riiklikule tervishoiuinstitutsioonile infosüsteemi riigis müüdavate farmaatsiatoodete haldamiseks. Lahe on! Plaani järgi jään siia 8-ks nädalaks, st. jõuan tagasi Eestisse siis, kui läheb tõsiseks robotiehitamiseks. Roboti ajud võtsin praegu kaasa ning saan siin vaikselt lõputöö/robotexi asjadega jätkata. Loodan, et jõuan siin ära teha tubli osa lõputöö tehnilisest poolest ning lisaks ka muud botmasteri platvormi uuendused, mis detsembris Robotexi võistlusel käiku lähevad.

Fancy thesis lab @ Stockholm. Kõikides knowiti korterites on by default monitor ja klaviatuur,  nende pärast muretsema ei pidanud - panin vga juhtme taha ning hakkasin tegutsema.

Enne minekut saime Valduriga kokku. Istusime 3-4h, arutasime ja analüüsisime erinevaid lahendusi, mis võiks uue roboti peal kasutada, eelkõige siis tarkvaralisi ja seoses uue väljaku iseärasustega. Samuti näitasin talle, mis ma vahepeal olen teinud.

Nii sünnivad meil uued lahendused ;)
Õhtu enne lendu avastasin, et ei saa ju kaasa võtta jurakat IT Kolledži toiteplokki.  Lõpuks ohverdasin oma digiboxi 12V 1.5A toiteploki ja jootsin juhtmed roboti ajude pistiku külge. Lennujaamas tekitasid palju ärevust roboti emaplaat ja muud elektroonilised komponendid, mis on mul hoolikalt akutrelli koti seinte külge teibitud - paluti detailid üksteisest eemaldada ja laduda ükshaaval halli karpi. Seletasin, et see on tavaline lauaarvuti, aga lihtsalt kere on riidest.. it worked, lol

Viimasest blogipostitusest kuni lennuni Rootsi tegelesin sellega, et uurisin põhjalikumalt botmasterit ning "koorisin" eelmises postituses mainitud multithreadilise opencv näidisprogrammi lähtekoodi. Eemaldasin funktsionaalsuse, mida me ei vaja ning suure osa sellega kaasnevast ebavajalikust qt gui kihist. Ühesõnaga valmistan ette integreerimiseks botmasteri platvormi sisse.

Plaanid lähitulevikuks
  • Täiustada veidi botmasteri timerit(autor Silver Kuusik) ning teha praegusele botmasteri jõudlusele põhjalik mõõtmine - tulemused saab nanosekundilise täpsusega. Nimelt paljas fps on üsna tühine näitaja. Mind huvitab, kui palju läheb aega igale eraldiseisvale protsessile, mis toimub ühe kaadri töötlemisel: kaadri haaramine kaamerast, värviruumide konverteerimised (YUV-RGB, RGB-HSL), objektide tuvastamine jms. See on väärtuslik info, mida pärast lõputöös kasutada.
  • Integreerida botmasterisse uus ettevalmistatud kiire multithreadiline tükk.
  • Asendada olemasolev botmasteri cvNamedWindow-il baseeruv graafiline liides. Asemele tulevad kergemad ja moodsad QtGui vahendid - liidest saab disainida drag&drop-ides. Uus gui engine tuleb tegelikult koos eelmise punktiga, tuleb lihtsalt vana liidese pildi kalibreerimise trackbarid uuesti realiseerida.
  • Eemaldada opencv-ga ekraanile joonistatav info. Igasugune üleliigne joonistamine sööb mingil määral jõudlust, fps-i ja muud numbrilist infot saab kirjutada tekstiväljadele pildi alla.
  • Pärast integreerimist teha uued mõõtmised ning salvestada tulemused. Ootuspärane uus keskmine jõudlus on 30+fps.
  • Uurida opencv "kõhus" toimuvat YUV-RGB konverteerimist. Ehk annab parendada opencv lähtekoodi ning asi läheb kiiremaks. Botmasteris on olemas väga kiire RGB-HSL konverteerimise algoritm. (võtab küll päris palju mälu, aga tulemus on väga hea) Võib proovida analoogset kasutada, kui seal pole.
  • Uurida, kas tasuks lisada botmasterisse uus "contest mode". Minu teada hetkel konverteerime pilti RGB formaati vaid selleks, et seda kuvada (Kaameral endal RGB väljundit ei ole, kaamerast tuleb YUV). Kuvamisel on tegelikult väärtus vaid roboti testimisel ja pildi kalibreerimisel. Pildi konverteerimine ja kuvamine sööb mingil määral jõudlust. Kui robot võistleb väljakul, siis tegelikult RGB pildi järele vajadust ei ole. Teooria: võiks olla nii, et ühe nupuvajutusega läheb robot "contest mode-i" ehk pilt konverteeritakse vaid ühe korra YUVist HSLi ning kuvamist ei toimu üldse. (Muidu on tsükkel: YUV->RGB, pilt, RGB->HSL, objektide tuvastus) Kaadrite töötlemiskiirus kindlasti mingil määral paraneks.
  • Eemaldada botmasterist vanade robotite hinged, kompileerimisel kulub nende peale mõttetult palju aega.. milleks neid ikka build-ida, nende aeg on läinud :D
Hetkel tegevusi küllaga, aga list kindlasti täieneb, mõtteid on veelgi ;)


Tack för att du läser!

Thursday, August 2, 2012

Chapter 1 - Double migration

Migration one:
Nokitsesin algul enda tööarvutis, kuid kaua see kesta ei saanud. Roboti tagasihoidlikku "aju" ei saa võrrelda multituumalise i5-ga. Mõõtmiste tulemused peaksid olema ilmselt liiga erinevad, nii mulle tundub. Nüüd siis paigaldan arenduskeskkonna roboti enda arvutusmasinale ning edaspidi jätkan ainult "seal".

Migration two:
Koolis ei saanud lõputööga tegeleda - õhtuti aetakse minema.
Kodus ei saa lõputööga tegeleda - kodu on puhkamiseks.
Kolisin koos kõikide vajalike komponentidega tööle - õhtuti on siin hea produktiivne õhkkond, kodule oluliselt lähemal ja satun siia tihti :P
(15x15cm Intel Desktop Board emaplaat , mille mudelit ma ei teagi+ kingston ssd ketas, dc power supply, paar PS3Eye kaamerat)

lab @ knowit
Action:

Varasemalt olen koodikirjutamise seisukohalt kokku puutunud vaid roboti käitumisloogikaga, mis on suhteliselt lihtne. Asi piirdus geditiga. Praegu oleks gedit overkill.. or underkill. Ja eriti veel sellepärast, et C++ on minu jaoks võõras, tööl olen tegelenud 99% javaga, koolis 75% :P. Java ja C++ on ikka meeletult erinevad, väga paljusid asju veel ei tea ja lugemist on väga palju. Õnneks on netis palju häid õpikuid.

Tõmbasin linuxi C/C++ eclipse. Eclipset teatavasti ei ole vaja "installeerida" ning siin mingeid jamasi ei olnud. Huvi pärast tõmbasin juurde mingeid Qt pluginaid ka. Kulus ikka aega, et eclipsest botmaster käima saada (mingite teekidega oli lõpuks ikka mingi kamm, osa koodist sai esialgu välja kommenteeritud). Eclipse buildib seda projekti 100 aastat. Ebamugav.
Eclipse + botmaster
Tahtsin Qt Creatori peale panna, kuid siin mul juhtus nagu Laaril - ruum sai otsa. Robotil puudus varem SSH ketas ning bootisime 8-gigase usbi pulga pealt (läheb ka eelmise pildiga kokku :D) ja nii oligi jäänud, et arvuti ainus partitsioon on 7,5 gigane. Qt Creator palus 4gb vaba ruumi.
Tuli siis muretseda GParted ning partitsiooni laiemaks venitada.
Qt Creator installeerus kaua, sest tõmbas oma sõltuvuste rahuldamiseks pool internetti alla. Käisin vahepeal kinos.

Tulin kinost tagasi ja jäi vaid klikata paar "next"-i ja üks "finish".
Botmasteri *.pro projekt oli roboklubi svn-is ka olemas. Avasin selle Qt arenduskeskkonnas and it worked like a charm - avab ruttu, buildib ruttu, jooksutab ruttu. Mõnus.

Ah, see tekst on nagu mingi jutt, see pole plaanipärane ja kribamise peale kulub liiga palju aega, katsun üle minna "märkmete" režiimi.

Research:

Leidsin huvitavaid näiteid pilditöötluse algoritmidest ja nende parendusest. Parim leid ja inspiratsioon esimesteks katsetusteks - http://code.google.com/p/qt-opencv-multithreaded/
  • +
  • Ilus kood, põhjalik dokumentatsioon
  • Põhiline väärtus seisneb threadide kasutamises - kasutatakse Qthreadi võimalusi
    • Värskeim opencv ja lahedad qt vidinad
    • Dedicated thread to capture frames from camera. 
    • Dedicated thread to perform image processing on captured frames.
    • Option to drop frame if image/frame buffer is full
    • Näited OpenCV funktsioonide kiirendamisest:
      • Smooth (Blur, Gaussian, Median) - kümnesse
  • muud
Väga väärtuslikud näidislahendused, mis võivad olla väga kasulikud ja mida võiks integreerida/meie süsteemi üle võtta. Ettevaatlikuks tegi üks avastatud bugi fps-i kuvamise funktsionaalsuses.

Testing:

Oma arvutis oli ilus tulemus, kaamerast tuli 30fps. Koos gaussi filtriga (kernel width/height: 7/7, X/Y sigma 0/0) jäi "pildi kuvamise" kiirus sisuliselt samasuguseks nagu pildi "pildi võtmisel", või noh.. halvimal hetkel 2fps aeglasem. Ilma puhvrita - robotil peaks olema n-ö LIFO "pilditöötlemispoliitika" - last in, first out. Kui robot jõuab võtta rohkem pilte, kui suudab töödelda, siis tuleb vahepealsed kaadrid minema visata.

Roboti arvutis oli tulemus natukene aeglasem. Aga muidu tulemus sama - kui gaussi filter peale panna, siis jõudluse kadu ei näe.

Probleem ja challenge: Oleks vaja kaamerast välja võluda rohkem kaadreid sekundis, riistvara võimaldab (max 125fps@320x240 ja 60fps@640x480). Olemasoleva kaamera driveri (ov534) lähtekoodi uurides selgub, et teoreetiliselt ka draiver peaks lubama. On vaja 60@VGA.

OpenCV kaudu rohkem "paluda" ei õnnestu. Küll aga õnnestus opencv funktsionaalsuse abil muuta pildi resolutsiooni (Valdur rääkis, et nii ei saanud varem. WIN!):
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 640); //töötab
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480); //töötab
    cap.set(CV_CAP_PROP_FPS, 60); // ei tööta
    cap.set(CV_CAP_PROP_BRIGHTNESS, 249);  //töötab
Vanemast ov534 draiverist (aasta 2009 vms) oli olemas patchitud versioon, kus capture fpsi sai muuta modprobe abil käsurealt. Aga sellel vanal draiveril polnud V4L tuge, mis on halb ja meile ei sobi. Umbes selline oli Marguse kommentaar.

Võib siis otsida adekvaatseid variante, kuidas seadistada kaadrite arvu või siis minna kiiremat ja põnevamat teed, h4xxida driverit ennast.. lähtekood on ju olemas.

OV534 Driveri Hakkimine:

Okei, vaikimisi lähtekoodi ei ole ja see tuli tõmmata.
sudo -s
cd /usr/src
apt-get update
apt-get install -y build-essential kernel-package linux-source guvcview
tar --bzip2 -xvf linux-source-*.tar.bz2
ln -s `find . -type d -name "linux-source-*"` linux
Täisa mõnus on kasutada neid '*' tähekesi, tihti on tutorialides taolises kohas miski a la '<your version>' (nt robo wikis on) ja siis tuleb see käsitsi asendada.

"ov534" draiveri lähtefail asus nüüd siin ("linux" kaust on symlink, nii on edasi mugavam): "/usr/src/linux/drivers/media/video/gspca/ov534.c" ja enne näppimist tegin koopia ka.
Driveris endas tegin väga lihtsa muudatuse, kahes massiivis kommenteerisin välja kõik muud reso ja fps optsioonid peale selle, mis mul vaja - 60fps@VGA.
Minu kerneli draiveris read 621-636
Enne:
    static const struct rate_s rate_0[] = {    /* 640x480 */
        {60, 0x01, 0xc1, 0x04},
        {50, 0x01, 0x41, 0x02},
        {40, 0x02, 0xc1, 0x04},
        {30, 0x04, 0x81, 0x02},
        {15, 0x03, 0x41, 0x04},
    };
    static const struct rate_s rate_1[] = {    /* 320x240 */
        {125, 0x02, 0x81, 0x02},
        {100, 0x02, 0xc1, 0x04},
        {75, 0x03, 0xc1, 0x04},
        {60, 0x04, 0xc1, 0x04},
        {50, 0x02, 0x41, 0x04},
        {40, 0x03, 0x41, 0x04},
        {30, 0x04, 0x41, 0x04},
    };
Pärast:
 static const struct rate_s rate_0[] = {    /* 640x480 */
        {60, 0x01, 0xc1, 0x04},
        //{50, 0x01, 0x41, 0x02},
        //{40, 0x02, 0xc1, 0x04},
        //{30, 0x04, 0x81, 0x02},
        //{15, 0x03, 0x41, 0x04},
    };
    static const struct rate_s rate_1[] = {    /* 320x240 */
        //{125, 0x02, 0x81, 0x02},
        //{100, 0x02, 0xc1, 0x04},
        //{75, 0x03, 0xc1, 0x04},
        //{60, 0x04, 0xc1, 0x04},
        //{50, 0x02, 0x41, 0x04},
        //{40, 0x03, 0x41, 0x04},
        //{30, 0x04, 0x41, 0x04},
    };
Nii lihtne ongi.
Tegelikult võtsin veel välja ka kaamera punase tulukese põlemise, ledi värv läheb punaste pallidega kokku, roboti katsetustel võib häirida :))
Kuna testisin mitu korda ja erinevat moodi, siis tegin draiveri kompileerimiseks shelli skripti ja aina käivitasin seda..
#!/bin/bash
# Rebuild OV534
echo "[Neve v3 arendus] Ehitan draiverite moodulid: ov534, gspca_ov534, and gspca-main..."
cd /usr/src
cp -p linux-headers-$(uname -r)/Module.symvers linux
cd /usr/src/linux
make oldconfig
make modules_prepare
make SUBDIRS=drivers/media/video/gspca modules
echo "[Neve v3 arendus] Paigaldan uue gspca_ov534 draiveri + asendan gspca_main..."
cd /usr/src/linux
cp -p drivers/media/video/gspca/gspca_main.ko /lib/modules/$(uname -r)/kernel/drivers/media/video/gspca
cp -p drivers/media/video/gspca/gspca_ov534.ko /lib/modules/$(uname -r)/kernel/drivers/media/video/gspca
depmod
echo "[Neve v3 arendus] Kustutan vanad draiverid, laen uued.."
modprobe -r gspca_ov534 gspca_main
modprobe gspca_ov534
Testing:

Põhimõtteliselt tänaseks kõik. 60fps puhul on juba näha, et töötlus jääb maha, aga siiski tulemus on täitsa vinge:
640x480 pildi kuvamine koos gaussi filtriga (kernel width/height: 3/3, X/Y sigma 0/0 - nagu meie robotil on olnud seni): capture rate hüppab vahemikus 45-59fps, processing rate ~45fps. Kui processing threadile kõrgem prioriteet määrata, siis tulemused paranevad.

Botmasteril on selline jõudlus  hetkel vaid siis, kui gaussi filter ja LUT(bgr->hsl) on välja lülitatud. Seega testitud lahenduste kasutuselevõtt võib tublisti parandada jõudlust.

Loodetavasti olen õigel teel :)



Licence and readme - human readable text

Olen juba mõnda aega tegelenud lõputöö asjadega. Blogi idee tekkis siis, kui migreerusin ühest arvutist teise ning pidin osa protseduuridest uuesti tegema. Kui mul oleks olnud märkmed, siis asi oleks palju mugavam.

Mu lõputöö on (võiks olla) seotud videotöötlusega reaalajas, õigemini selle jõudlusega ning veel täpsemalt selle jõudluse tõstmisega. Katsejäneseks on EIK robotiklubis (Koht, kus ehitatakse ja arendatakse võistlusroboteid) loodud plavorm botmaster, mille üks tähtis komponent on robovision - see, mis võtab kaamerast pildi, töötleb seda, analüüsib leitud objekte ning aitab robotil võtta vastu otsuseid, kuidas konkreetses situatsioonis käituda. Tegelikult saavad meie robotid 85% kasulikust infost just läbi kaamera silma (~nagu inimenegi), seega antud komponent on kriitilise tähtsusega. Kui peaks juhtuma, et robot kaotab oma kompimismeele (nt. infrapuna-andurid), siis jääb teoreetiline võimalus, et masin suudab teatud olukordades perfektselt jätkata oma tööd. Juhul, kui kaob nägemine (Nt. kaamera rike), on olukord lootusetu. Mõistagi videotöötluse/analüüsi kiirus mõjutab otseselt seda, kui kähku suudab robot võistlusplatsil opereerida. Mida väiksemad kosteajad, seda kiiremad liigutused - lihtne :)

Otsin, analüüsin, nuputan, arendan lahendusi, kuidas teha olemasolev asi kiiremaks: pilditöötluse tarkvaralise komponendi üldine arhitektuur, algoritmilised lahendused, riistvara külg - analüüsida saab kõike. Muidugi pean looma mõistliku ja lihtsa metoodika, kuidas seda "jõudlust" üldse mugavalt mõõta. Tundub just selline teema ja eesmärk nagu vaja - kitsas ja konkreetne, kuid käed on üsna vabad.

Lõputöö võib olla meeletu ajaraiskamine ning seetõttu on mul lõputöösse suhtumisel kaks põhilist põhimõtet - ma pean sellest kasu saama, teised peavad sellest kasu saama.
Ma olen motiveeritud ning soovin teha hea lõputöö selleks, et:
  • lõpetada ülikool ning minna edasi õppima (you don't say meme)
  • õppida ja areneda
  • loodan, et saan olla oma tööga kasulik kogu robotiklubile, sest robovision on meil kasutusel kõikide tiimide robotites

Et jah, see on siis blogi readme. (Kui keegi juhtumisi satub siia ning ei saa aru, mis asi see veel on)