Developer blog / University Projects

SzakdolgozatEl is készült a bekötése a szakdolgozatomnak. A cím, mint azt korábban is írtam „Gráf-alapú Egyidejű Lokalizáció és Térképezés”. Mindennel együtt 92 oldal és 20157 szó lett a Word szerint. Amint az egyetem kirakta a publikusan elérhető digitális archívumába, megosztom majd itt is, de addig is most az államvizsgára koncentrálok.

Pózolás meg jobb minőségű kép az most elmaradt, mert gyorsan be kellett adnunk.

Még karácsony előtt lőttünk pár új jelenetet a szakdolgozat projektben. Az egyik jobban sikerült jelenetből összeállítottam az alábbi kis videót. A helyszín az egyik egyetemi labor.

Ami a videón látszik: betölt fájlból egy korábban kimentett jelenetet, szeletenként, majd az egészet kitörli és a csúcspontokból generálja ki újra. A végén pedig végigrepül a csúcspotokon, ezzel követve azt az utat, amit eredetileg a kamera megtett.

Megkaptuk az első helyezést a projektünkre a 2015 őszi Tudományos Diákköri Konferencián.

TDK első díj

Mint azt már korábban is írtam, a projekten ketten dolgozunk, Takács Dániel kolléga Úrral, melynek címe:

Gráf-alapú Egyidejű Lokalizáció és Térképezés.

Projektünk alapvető célja egy olyan szoftverrendszer elkészítése, amely képes egy Microsoft Kinect szenzor jeleit feldolgozni és ezek alapján feltérképezni a környezetét. A feltérképezett munkatér ezek után virtuálisan bejárható, illetve a munkatérben lehet útvonalat keresni, és ez alapján dönt a rendszer arról, hogyan navigálhat az ismert területen. A rendszer érzékeli, ha egy már korábban feltérképezett térrészt újra azonosít, és javítja a térképet a régi és az új adatok segítségével. Figyelembe véve a szenzor által szolgáltatott adatokban fellépő zajokat, a modellel szemben elvárás, hogy minél pontosabban közelítse a környezetet, amelyből alkotja azt.

A projekt jelenlegi állapotában a kamerát kézben visszük, ez főleg tesztelésnél gyorsabb is. Az alábbi videóban a TDK előadás során is felhasznált videóanyagot szerkesztettem egybe (magyarázat a videó után).

Feltérképezés

Első lépésben történik a feltérképezés, ilyenkor a kamerát (világoskék nyíl) végigvezetjük a feltérképezendő térben, a program pedig igyekszik a képekből meghatározni a térbeli elmozdulást. Hogy spóroljunk az erőforrásokkal, a program csúcspontokkal dolgozik (a sötétkék nyilak), ahol nem az egymás után következő képkockákat veti össze, hanem mindig az aktuális képet az utolsó csúcspont képével. Új csúcspontot akkor rak le, ha az előző óta az elfordulás vagy elmozdulás egy bizonyos értéket meghaladott.

Az egyes képkockák közti relatív elmozdulást könnyedén ki tudjuk számolni, mivel a Kinect szenzor biztosít az egyes pixelek mellé mélység adatot is, így miután kinyertük a közös jellemzőket a két képen, lesz két pontfelhőnk, amik ugyanazokat a pontokat írják le, csak más orientációban és elhelyezésben.

A térképezés során minden csúcspont lementésekor a hozzátartozó kép képpontjait leképezzük a voxel térbe. Itt nagy voxelekkel dolgozunk, és nem minden pixelt számítunk be, így egy gyors, vázlatos képet kapunk arról, hogy milyen lesz. A csúcspontok ismeretében a voxel teret bármikor és bármilyen felbontásban újragenerálhatjuk.

Útvonalkeresés

Az útvonalkeresésnél a legfontosabb, hogy a padlót külön tudjuk választani a többi objektumtól. Noha a padló sík, a különféle zajok és pontatlanság miatt soha nem lesz tökéletesen sík, így a padló kiválasztásánál ezt figyelembe kell venni, hogy hol van az, ahol egy voxel ugrás még zaj, és hol számít már akadálynak. Ennek a végeredménye egy 2D térkép lesz, amiben gyorsan és könnyedén tudunk Dijkstra-féle hullámtovábbterjesztéses algoritmussal útvonalat keresni. Mivel ez az algoritmus nem számol fizikai kiterjedéssel, így magát az utat kell lesoványítani úgy, hogy az akadályokat hízlaljuk fel a robot méretével. A videón ezt jelzik a színek: a piros szín mutatja azt a padlórészt, ahol nem férne el a robot, a zöld pedig a járható utat.

3D megjelenítés

A videó utolsó része egy ilyen nagyfelbontású voxel tér körbejárását mutatja be. Itt a kamera a csúcspontokat járja végig időrendi sorrendben.

Megtartottuk a második előadásunkat is a Tudományos Diákköri Konferencián. A projekt ugyanaz mint tavaly, ami egyben a szakdolgozat projektünk is, amin Takács Dániel kollégával közösen dolgozunk. Tavaly óta gyarapodtak az eredmények és a cím is kicsit specifikusabb lett, mégpedig Gráf-alapú Egyidejű Lokalizáció és Térképezés.

Az elektronikás projektek most jegelve vannak az egyetemi félév idejére, de az egyetem kapcsán is jó sok érdekes feladat van. Köztük a robotika szakirány a 3 féléves projektmunkájával, melynek során egy olyan szoftvert készítünk, amely képest egy Kinect szenzor jeleivel feltérképezni a környezetét és ebben útvonalat keresni. Ez egyelőre erősen alfában van, úgyhogy erről konkrétabbat majd csak később.

Ami viszont egybevág a hobbiprojektjeimmel: a következő nagyobb videojáték munkámat mindenképp voxel alapokra akarom helyezni, és ezt csak elősegíti az, hogy a robot projekt is voxeleket használ, és a GPU Programozás tárgy keretein belül is voxel render-t írok CUDA-ra. Mire oda jutok hogy a játékot elkezdjem, már lesz konkrét elképzelésem róla, hogy mit hogyan érdemes.

Gondoltam megtöröm itt kicsit a csendet. A rendes nagy projektjeim még váratnak magukra, nyárig garantáltan nem lesz rájuk egy percem se, pedig nagy ötleteim vannak. Előtte még jó eséllyel publikálni fogok egy party-kellék programot amin az utóbbi időben dolgoztam, erről majd még részletesebben beszámolok.

Addig is, Beágyazott Rendszerek Gyakorlata óra, avagy hogyan írjunk .NET Micro Framework alapú eszközre Space Invaders-t másfél óra alatt. :D

Az utóbbi időben ezerrel dolgoztam a sulis és egyéb projektjeimen, ezek közül szeretnék bemutatni egyet az előbbiek közül:

Codename Z: Incomplete Operation

A Vizuális Eseményvezérelt Programozás nevű óra keretében kaptuk a feladatot, hogy írjunk egy játékot, úgyhogy írtam egyet. Persze azért ebben rengeteg órányi munka és legfőképp korábbi tapasztalat van, szóval így könyű (könnyebb), hogy nem idén látok először programkódot. A játékkal meg is nyertem az első díjat a tárgyhoz tartozó programozási versenyen, amin minden osztályból a legjobb féléves munkák indultak.

Vizuális Eseményvezérelt Programozás verseny 1. díj

Maga a játék szörnyen egyszerű, A pontból B pontba el kell jutni egy darabban, közben zombik és trollface-ek hada próbál megállítani minket, és ha ez nem lenne elég, a létesítmény automata biztonsági rendszere is az ellenségünk! De nem kell kétségbe esni, a pálya tele van lőszerrel és elsősegélycsomagokkal.

Felülnézetben fedezhetjük fel ezt a veszélyes világot, ahol fontos szerepet játszanak a fények. Ez már az elején nyilvánvalóvá vált, hogy fények nélkül túl üres lenne a pálya, így viszont jelentős szerepet kap a történet során az elemlámpa, melyet az F gombbal tudunk ki és be kapcsolni (Xbox Controller esetén B). A pálya több részén is koromsötétben kell utat találnunk, és közben visszaverni az ellenfeleket, de szerencsére ahogy mi sem látunk a sötétben, ők sem! Viszont ha túl közel kerülsz hozzájuk, megérzik a jelenléted!

Codename Z: Incomplete Operation

Az irányítás:


(Az Xbox Controller-t automatikusan felismeri indításkor, ha be van dugva. Felismer más gamepadokat is, de a gombok kiosztása azoknál eltérő lehet)

 

És persze nem utolsó sorban itt van a lényeg, maga a játék:
http://vbstudio.hu/games/codenamez-incomplete-operation

A programhoz a következőknek kell telepítve lenniük:

Az utóbbi kettő, ha van játék a gépeden, akkor már valószínűleg telepítve van.
Jó szórakozást! ;)

 

Most, hogy a lényeget már letöltötted, jön a kevésbé érdekes rész, a technikai infó :D

Hogy a félreértéseket elkerüljük, most előre kijelentem: a játék nem használ DirectX-et a megjelenítésre! OpenGL-t sem. Az egész játék a .NET 2.0 rendszer GDI+ API-ját használja a grafikák kirajzolására. Részben ezt, és részben közvetlenül végez számításokat a memóriában. Ez az összetettebb képszámolásoknál kell, a fények kirajzolásánál, illetve az ütközéstérkép olvasásánál, mert ezeknél rendkívűl fontos a sebesség, és a beépített Bitmap.GetPixel() nem képes ezt a teljesítményt szolgáltatni. Ennek az oka egyszerűen az, hogy a GetPixel() minden híváskor lezárja a bitmapot a memóriában, kiolvassa azt az egy pixelt, aztán fölszabadítja, és ezután a kiolvasott pixelnek még létrehoz külön egy Color objektumot. A közvetlen memória írásnál és olvasásnál csak egyszer zárja le a bitmapot, és addig nem szabadítja fel, amíg az összes pixelműveletet el nem végezte, a pixeleket pedig byte formájában olvassa ki pointer-ek segítségével.

A program egyetlen egy helyen használ DirectX-et, mégpedig a joystick kezeléséhez.

A hangokat az irrKlang hang library biztosítja. Csak ajánlani tudom, mert bárki számára szörnyen egyszerű a használata. Az alábbi linken érhető el:
http://www.ambiera.com/irrklang/