Bevezetés
Új nagy projektbe vágtam, valószínűleg majd naponta írogatok valamit, hogy aznap épp mivel ütöttem el az időt, illetve milyen fontos dologra jöttem rá a projekt kapcsán.
Adott két kamerával rendelkezdő SVS robot, ezzel kell majd pár dolgot megalkotnom.
Még nem árulom el a végét, mert még eldöntve sincs, attól függ, mennyire tudok haladni.
Néhány dolog azonban biztos:
A robot csak a képeket fogja küldeni és teljesíteni a parancsot, tehát a programvégrehajtás a PC-n lesz.
A PC-s progi C++ nyelvben íródik, és használja az OpenCV függvénykönyvtárat.
A robot
SVS
Forrás: http://www.surveyor.com/
SRV-1, az eredeti egyszemű, a robot elején az a két sárga a lézeres távolságmérő.
Lánctalpaival tud mozogni, akár egész gyorsan is, de eléggé fejnehéz, így vigyázni kell a hirtelen mozdulatokra.
A robot "feje" egy ilyenen csücsül. Képes a fejet horizontálisan és vertikálisan is mozgatni, lényegében kötelező bekapcsolni, mert olyan nehéz a fej, hogy kicsi mozgás hatására is elmozdul.
Egy nagyon fontos kép, hogyan kell bekötni a robotot:
Ugyanis a gyártó semmilyen használati, bekötési útmutatót nem mellékelt, így a netről nekem kellett összehalászni, mit és hova kell. Szerencsére nem sütöttem ki a robotot .
AForge.NET oldaláról letölthető egy egyszerű távirányító a robothoz.
Az első mérföldkő Határidő: augusztus 24.
1. Robot távvezérlése saját programmal
2. OpenCV (IplImage) kapja meg azt a képet, amit a robot küld.
1. Robot távvezérlése saját programmal
Ez gyakorlatilag kész van, ehhez felhasználtam az SDL függvénykönyvtárat, azon belül az SDL_Net-t.
A motor és a szervók direkt vezérlése is meg van oldva.
2. OpenCV (IplImage) kapja meg azt a képet, amit a robot küld.
Na itt kezdődnek a gondok .
A robot egy jpeg fájlt küld el, amit fogadni és lementeni is tudok. A B terv az, hogy lementem a képet, aztán cvLoadImage() függvénnyel meghívom. Ez nem túl szép megoldás (ráadásul nem is működik még rendesen), a sebesség miatt a memóriában akarom elvégezni a konverziót.
Sikerült valamit összeügyeskednem: CxImage és eme hozzászólással végre sikerült, bár a kép valamiért fejjel lefelé van, de OpenCV-vel ezt már meg lehet oldani: cvFlip().
Bizonyíték (OpenCV ablaka)
screenshot
Kb. 3 napi szívás után talán sikerült...
Először valamiért azt hittem, hogy TCP-n keresztül bitmapként jön a kép (pedig világosan le van írva, hogy JPG, lehet túlzottan reménykedtem), aztán próbáltam IplImage->imageData-ba egy az egyben átmásolni, persze, hogy marhaság lett a vége. Fel is tűnt, hogy a kapott 320x240-s kép kb. 9000 elemű char tömbben elfér, ráadásul ez változó volt, míg az OpenCV 230400 (320*240*3) eleműben tárolta. Keresgéltem, manuálisan hogyan kell JPG-ből OpenCV-nek tetsző bitmapot csinálni, de arról inkább letettem.
Éjjel (mivel annyira felidegelt a probléma, hogy nem bírtam már aludni se 3 napja) eszembe jutott, keressek rá a JPG dekódolása a memóriában szavakra (angolul persze), végül eljutottam a fent linkelt oldalakra. Nagy mázli, hogy a CxImage szó nélkül lefordult VS2008 C++ alatt.
Másik megoldás talán az lett volna, ha a cvLoadImage() függvényt felüldefiniálom, tehát nem a vinyóról beolvasott fájlból olvas, hanem egy adott tömbből, de ehhez én már kevés vagyok.
Akkor a következő feladat, hogy a "rendes" kódomba átültessem ezeket, mert a tesztelés innen-onnan összemásolt kódokból van megvalósítva.
Plusz van egy hibája, hogy a keletkezett IplImage-t nem tudom törölni, így csak előre beadott felbontással működik (második cvCreateImage()-nél egész egyszerűen elszáll). Valószínűleg ott a hiba, hogy a cvReleaseImage() is elszáll, így ki kellett kommenteznem, szinte biztos, hogy az átmásolt adatok miatt képtelen törölni.
Előbb írt hiba volt tényleg az oka, másik másolási módszerrel már minden rendben.
( Augusztus 7-ei adásnak vége )