Advanced Robotics Challenge – World Robot Olympiad 2020

Advanced Robotics Challenge – World Robot Olympiad 2020

Loading Likes...

A verseny

Albert Mártonnal, Umann Dáviddal, és magammal (Tóth Ambrussal), a tavalyi WRO csapatommal idén is neveztünk a World Robot Olypiad versenyre, ezúttal viszont az Advanced Robotics Challenge-re. A feladat pontos kiírása elérhető ezen a linken, de igazából csak annyi a lényeg, hogy építsünk egy robotot, ami képes kockák színét felismerni, és kis kockákat elszállítani egyik doboz tetejéről a másikra. A robot építése során bármilyen anyagot, szenzort, motort és vezérlőegységet használhatunk, az egyetlen megkötés a méret (34,5cm élű kocka), és hogy nem használhatunk vezeték nélküli kommunikációt a futam során.

A robotunk terve

A robot pontos kinézete építés közben alakult, itt látható az eredeti elképzelésünk:

  • 4db omnikerék a könnyű kétdimenziós mozgáshoz
  • 4db távolságérzékelő szenzor, hogy minden irányba tudjuk érzékelni, hogy van-e az adott mezőn kocka
    • 1db lézeres távolságmérő a robot elejére, hogy amikor odamegyünk a doboz elé, pontosan tudjuk magunkat pozícionálni (ez nem kellett)
    • 2db nyomásérzékelő szenzor (nyomógomb), hogy még sokkal pontosabban tudjunk parkolni
  • A kockaemelőhöz kell pár szervómotor.
  • Egy kamera a robot elejére a QR kódok leolvasásához, valamint az X irányú pozícionáláshoz képelemzéssel (ez még nem biztos, hogy fog működni [spoiler: de]).

Az alap és a kerekek

Célszerű lentről fölfele haladni, így először a robot vázát építettük meg fémcsövekből. A gondok itt kezdődtek, mivel valahogy a motorokat föl kellett volna erősíteni erre a keretre, mi viszont csak 1db rögzítőelemet kaptunk a csomagban, mert már használt készlet, és a korábbi csapatok elhagyhatták.

Nagyjából ezen a ponton döntöttük el, hogy kimenekítjük az iskolából a robotot, és az összes alkatrészt, mert már nagyon közelgett az iskolabezárás a koronavírus miatt. 2 nappal később, pénteken jelentették be, hogy határozatlan ideig nem mehetünk iskolába, így örültünk, hogy már kipakoltunk. A karanténnak egyébként pozitív hatása van a munkánkra, mert az utazások hiánya, és a meg nem tartott órák miatt rengeteg szabadidőnk van.

Nálam itthon van egy 3D nyomtató, amit az NTP-NFTÖ pályázaton kaptam, és a 3DJake webáruház támogatásának hála kaptunk 1kg PLA filamentet, aminek a tartósságát és erősségét a készülés és a futamok során fogjuk tesztelni. Az előbbi hiányzó alkatrész elég egyszerűnek tűnt, úgyhogy lemodelleztük Dáviddal Fusion360-ban, majd kinyomtattam 4 példányban.

Felszereltem a motortartókat az alvázra, és rögzítettem a motorokat. A következő probléma az volt, hogy nincsen 4db omnikerék a készletben, így a 2019-es First Global Challenge-ről maradt kerekeket kellett használnunk, amik viszont nem kompatibilisek a motorjainkkal, úgyhogy erre is kellett terveznünk egy kiegészítőt. A kerekeket először ki kellett fúrnunk, hogy beleférjen a lecsapott élű motortengely, majd ráragasztanunk a 3D-nyomtatott bővítményt, és egy tengelyszorítót.

A beragasztott tengelyszorítót meghúzva stabilan rögzíthető a kerék a tengelyhez:

Fel is erősítettem a motorokat a robotra, és írtam egy programot a Prizm Controllerre, ami a 4 motort egyszerre vezérli, és egy előre-hátra mozgást végez.

Robot teszt

Az eredmény elég szomorúnak tűnt, random oldalmozgásokat végzett a robot, miközben ment. Össze szerettem volna szinkronizálni a motorok forgását, hogy biztosan azonos sebességgel menjenek. Ehhez szükségem lett volna viszont a motorok állására, azaz az enkóderük értékére. Valamiért a Prizm Controllerben ennek az adatnak a lekérése nagyon lassú művelet, és másodpercenként csak ~5-ször tudta elvégezni ezt a műveletet a négy kerékre. Ezért úgy döntöttem, hogy ezt egy külön áramkörön valósítom meg, egy Wemos mini D1-gyel.

Készítettem egy kis bővítőpanelt a mikrokontrollerhez, amibe be lehet dugni a 4 motorenkóder kábelét, valamint a Wemos-t.

Mint utólag kiderült, a Wemos Mini D1 nem szereti, ha rá vannak dugva a szenzorok már bekapcsoláskor, mert egyes lábainak több funkciója is van, és összezavarja a bootolási folyamatot. Lehetett volna még tranzisztorokkal szórakozni, hogy lekapcsolják a szenzorokat a VCC-ről és a GND-ről (egy ilyen tranzisztor látszik az előbbi képen is), de nem jártam sok sikerrel, és egyszerűbbnek tartottam, hogy már az enkóderkövetést is a raspberry pi végezze el közvetlenül.

Bekötöttem a raspberry pibe a motorenkódereket egy saját készítésű adapterrel, és a motorokat irányító prizmmel soros porton kommunikáltam.

Minden működött technikailag, az enkóderpozíciók a PI-n számolódtak, soros porton elküldtük a prizmnek, hogy hány %-os teljesítménnyel hajtsa a motorokat, és írtunk egy PID szabályzót, ami elvileg stabil sebességen képes tartani a motorokat, a terhelésüktől függetlenül. Vagy azért, mert még nincs túl sok gyakorlatunk a PID állítgatásában, vagy a 20 milliszekundumos maximum frissítési frekvencia miatt (prizm motor controller limitáltsága) eléggé rosszul sikerült tartani a sebességet. Sikerült valahogy kiszednem az I2C kommunikáció utáni várakozást a prizm forráskódjából, így elég jól tartotta a tempót, viszont valami rettenetes hangot adtak ki a motorok működés közben, ami nem hiszem, hogy jót tenne nekik hosszabb távon, úgyhogy úgy döntöttünk, hogy inkább rábízzuk a PID szabályozást a Prizm beépített motor controller chipjére. Így egy bizonyos mértékű szabadságot elvesztünk a szabályzásból, de legalább működik.

Ekkorra már jól beleástam magamat a Prizm rendszerének működésébe. A lényeg nagyjából annyi, hogy a Prizm controllerbe épített Arduino egy I2C buszon kommunikál a motor controller chipekkel. Mivel az arduinora írt library-jük nyílt forráskódú, simán lemásolhatnám ugyanezt raspberry pire, és a Pi-t összekötve a Prizm I2C buszával már ki is hagyhatnánk az Arduinot az egész folyamatból. A Raspberry Pi-nél 3,3 voltos a logikai 1, az Arduinoban pedig 5V. A kettő rendszer összekötéséhez szükségünk lenne két multi-directional level shifterre (egyik az SCL, másik az SDA vezetékhez). Vettem egyet a hestore.hu-ról párszáz forintért.

A Pi valamiért nem látja ezzel a level shifterrel a csatlakoztatott eszközöket. Még mindig rejtély számomra, hogy miért. Pedig még egy szép 3D nyomtatott dobozt is csináltam neki… Építettem egy saját level shiftert 4 tranzisztorból és 6 ellenállásból, de azzal is csak annyira működött, mint a boltival.

Oké, még pár nap elvesztegetett idő, de egy óra sem veszett kárba, rengeteget tanultunk közben.

Újragondoltam a régebbi problémát. Írtam pár sor kódot a Prizm-re, ami egy egyenes vonalban mozgatja a robotot 45 fokban, 90 fokban oda-vissza. Rájöttem, hogy nem a motorok sebessége az, ami miatt elferdül a mozgás, hanem a kerekek csúszása. Próbáltam letörölgetni a port róluk, kisimítani a pályát amennyire csak lehet, de sose működött teljesen megbízhatóan. Ekkor eldöntöttük, hogy használunk hagyományos kerekeket a 4 omnikerék helyett.

Szétszedtük az egész robotot Dáviddal, és elkezdtük megtervezni az alapot. Két kerék oldalt, egy-egy golyókerék elől és hátul.

Az oldalmozgás hiányában kénytelenek vagyunk egy fogaslécet használni a kockák cserélésekor. Fogaslécet nem kaptunk a készletben, így ezt nekünk kellett legyártanunk. Szerencsére a weboldalon fent van az összes alkatrész 3D terve, így egyszerűen ki tudtuk nyomtatni őket. A csúszkán tettünk annyi módosítást, hogy összekötöttük a kettőt a fogaskeréknek hagyva egy lukat, ami miatt jóval tovább ki tud nyúlni oldalra.

Egy kis csiszolás, egy kis WD40, és kész is a príma fogaslécünk:

3D-nyomtattunk kerekeket, viszont túl csúszósak voltak. Próbálkoztunk lufit húzni a kerékre, hogy tapadjon, de folyton kiszakadt, ahogy fékezett és nyúlt az anyag. Ragasztottunk rá dekorgumilapot, de azzal még mindig nem volt elég tapadós. Hosszas gondolkodás után rájöttünk, hogy a legkevésbé csúszós anyag, amit ismerünk, az a lépcskön lévő csúszásgátló csík, ami gyakorlatilag egy csiszolópapír.

Ezzel természetesen pár milliméter pontossággal végig tudunk menni a pályán. A legnagyobb baj abból eredhet, ha kicsit ferdén indul a robot, mert az egyik keréknek az egyik oldalra van a kotyogása, a másiknak meg épp a másik oldalra. Reméljük ez kiküszöbölhető lesz azzal, ha a biztos pontoknál (a parkolóban és a kockáknál) két touch sensor segítségével be tudjuk pozícionálni a robotot.

Felszereltük a fogaslécet, és rá a kockamegfogó kart. Egy szervó tudja fel-le emelni a kart, egy másik pedig balra-jobbra megszorítani és elengedni a kockát.

A robot elejére került a két touch sensor, ami érzékeli, ha a robot bal, vagy jobb oldala falnak ütközött. Ezek segítségével tudjuk majd fallal párhuamosan pozícionálni a robotot, és esetleg a kockák detektálásában is szerepe lesz.

A QR kód olvasáshoz és színérzékeléshez felszereltünk egy kamerát szintén a robot elejére. Ennek a megbízható működéséhez egy LED-szalaggal világítjuk az adott tárgyat, hogy más fényviszonyoknál is megfelelően működjön. Egy fél napig kísérletezgettünk, mire rendesen fel tudta ismerni a kódokat. Két dolgot kellett figyelembe venni: ha túl közel vagyunk, akkor torz képet ad a kamera, mivel széles látószögű (~70°). Ugyanakkor ha túl távol vagyunk, akkor pixeles, vagy homályos lesz a kép. Rájöttünk, hogy hogyha 3 képet készítünk, majd azokat átlagoljuk, akkor egy pontosabb képet kaphatunk, ami megnövelte az esélyeinket a beolvasásra.

A kamera egyébként egy egyszerű USB webkamera, aminek eltávolítottuk a dobozát és egy könnyebben rögzíthető hátlapot nyomtattunk.

Miután működött minden, kiderült, hogy ez a Raspberry PI-vel nem kompatibilis, csak Windows-os és MacOS-es gépekkel. Rendeltünk egy eredeti Raspberry PI kamerát egy 50cm-es szalagkábellel, annak biztos jónak kell lennie hozzá. A 8 megapixeles verziót választottuk, ami az előbbi 0.9 MP-es kamerához képest nagyságrendi különbség, úgyhogy ezzel sokkal megbízhatóbb lett a működése, elsőre felismerte a kódokat a megfelelő képminőség és fókusztávolság beállítása után.

Készítettünk többféle kamerarögzítő modult, végül úgy döntöttünk, hogy a kamerának nem kell mozognia a karral együtt, így csak simán az alapra erősítettük:

A Raspberry Pi tápellátásához egy step-down convertert használtunk, ami a 14V-os akkumulátor feszültségét 5V-ra konvertálja. Hozzáforrasztottunk USB aljzatokat, így egy USB kábellel csatlakoztathattuk a Pi-hez.

A robotnak a tapasztalatok szerint a fordulási pontatlanságokból hamar összegyűlik nem elhanyagolható mennyiségű hiba. Erre kétféle megoldásunk született. Az előre-hátra pozicionálást a robot elején lévő nyomásérzékelők segítségével oldottuk meg. Elindítjuk mindkét motort, majd ha az egyik oldalon benyomódik a gomb, annak az oldalnak a kerekét megállítjuk. A balra-jobbra történő pozicionálást a kamera és egy kis trigonometria segítségével oldottuk meg. A kamera lefotózza a kockát, látja ez alapján, hogy milyen messze van a közepétől, majd a robot v-alakban bekacsázik a pontos helyre. Itt egy kis rajz a kerék fordulásának kiszámításához:

Ez kódban így néz ki:

A forráskód jelenleg három különböző projektből áll. Az útvonaltervező, a képelemző, valamint a robot kódja. Azért szeparáltuk ezeket az egységeket, hogy külön-külön is tudjunk rajta dolgozni, külön is tudjuk őket tesztelni. A képfelismerőt, valamint az útvonoltervezőt kibuildeljük .jar fájlokba, amit a robotra feltöltött kód projektje tud importálni. Az útvonaltervezőt Marci készítette, és írt hozzá egy grafikus megjelenítőt is, ami szépen animálva kijelzi a robot útvonalát egy megadott pálya alapján.

Köszönöm, hogy végigolvastátok a cikket, nagyon élvezetes volt ez a közel 9 hónapos építési folyamat… Végül itt egy videó a robot működéséről:

Még mindig van rajta mit csiszolni, a menetidőn biztosan javítani kellene, de szerencsére a motorok még nagyjából csak 20%-os sebességgel mozognak…

A cikk még folyamatosan bővülehet, addig is ha bármilyen kérdésetek van, nyugodtan keressetek meg emailen, vagy írjatok a komment szekcióba!

Leave a Comment

Az email címedet nem tesszük publikussá. A kötelező mezők *-ként vannak jelölve.

Show Buttons
Hide Buttons