A RobonAUT a BME Villamosmérnöki és Informatikai Karának éves versenye, melyet a kar mesterszakos hallgatóinak szerveznek évente. Volt szerencsém BSc-s létemre részt venni ezen a versenyen Havasi Dávid barátom meghívására. Ebben a cikkben megpróbálom összefoglalni, hogy mit adott a verseny és hogyan teltek a felkészülésünk hetei.
A verseny résztvevői a Robotirányítás rendszertechnikája nevű tárgy (jelenlegi és volt) hallgatói közül kerülnek ki. A pontosság kedvéért a tárgyat a BME bármelyik hallgatója felveheti, mint szabadon választott tárgyat. Mivel úgy gondoltam, hogy a mikrokontrollerek terén elegendő tudással rendelkeztem és szívesen csinálok hasonló dolgokat így ez a verseny is izgalmasnak ígérkezett.
Aki nem tudná, röviden összefoglalom: a verseny célja rendszerint egy akadálypálya és egy gyorsasági pálya időre történő teljesítéséből áll. A verseny résztvevői kapnak egy távirányítós autót és egyéb, a fejlesztéshez szükséges (és kötelezően használandó) alkatrészeket, laborhasználati jogot és konzulenst. A verseny állandó eleme egy felragasztott vonal követése. A csapatok felkészülését több alkalommal is ellenőrzik. Ebből az első kvalifikáció alkalmával demonstrálnunk kell az autó vonalkövetési képességeit. Ez a feltétele az autó megtartásának, ami egyben a jutalma a csapatnak, még ha nem is ér el helyezést versenyen. Szerencsére a legtöbb csapat a többi kvalifikációt is sikerrel teljesíti és így a versenyen is részt vehet.
A csapatnév eredetéről:
Ha valakinek volt szerencséje megjelenni a versenyen vagy esetleg látta a közvetítést, ott megpróbálkoztam értelmes mondatokba önteni a csapatnév eredetét. Ez egy sikertelen próbálkozásnak bizonyult a verseny előtti 24 órás kódolás és hibakeresés végtelennek tűnő káosza után. Bár az dicséretes, hogy még alapvető vegetatív funkcióim és pulzusom is volt.
Csak hogy kis betekintést adjak a verseny előtti éjszaka történéseiből, a csapatok szemszögéből. Ilyenkor helyezik el a pályát az aulában, ezért a csapatoknak ilyenkor adódik lehetősége az eddigi munkájukat egyben kipróbálni a korábban ismeretlen pályán. Ilyenkor végezzük az utolsó simításokat, a szabályzórendszerek hangolását és bizony itt jönnek ki a potenciálisan végzetes hibák is. Az ‘ugratón’ a kocsi elveszti a vonalat, kisodródik, leég a motor, későn lassít a kocsi meg hasonlók.
Tehát a csapatnév egy kósza ötlet volt. Mindig is rajongtam az elektromos autókért: a csendes üzemelésért, a jó hatásfokért, és persze a gyorsulásért. Innen jött a Tesla Monsters, mint a hétköznapi elektromos autók úttörője. A másik fele a névnek nem ennyire egyértelmű: az extrém sportok világa a folyamatos pörgés és az egyetemmel járó mértéktelen koffeinfogyasztás szimbóluma. Lehet ez csak személyes, de számomra ez egy életstílust is jelképez.
Honnan indultunk:
Mint senior csapat, nem a nulláról indultunk. A csapatban csak én voltam újonc, de a többiek már maguk mögött tudtak egy versenyt, ahol sajnos nem indulhattak, mivel a verseny előtti hajrában összetört a kocsi. Tehát az idei versenyt sok tapasztalattal és nem mellesleg egy jó hardverrel kezdtük. Innen jött a sok észrevétel, hogy tavaly mi nem működött jól és min tudnánk javítani.
A mechanika:
Az elsődleges célunk volt tanulni a tavalyi hibákból. Másik tényező a dologban, hogy szerettünk volna állapotteres szabályozóval indulni. Ez annyit jelent, hogy az autó érzékeli a vonal pozícióját és a kocsi tengelyével bezárt szögét (tehát a lényeges állapotait a kocsinak), így a szabályozókörünk lényegében sebességfüggetlen lehetett volna. Ez ugyan nem valósult meg, de ehhez egy, az akkori mechanikai váznál sokkal stabilabb, megbízhatóbb tartószerkezet kellett. A kapott Strada XT hobbi célokra egészen jó, sajnos azonban ilyen pontos szabályzásra nem alkalmas. A kerekek lötyögése, az első kerékmű esetén különösen megnehezítette volna a pályán maradást. Az első ackermann kormányzás és az erőátviteli karok holtjátéka a szabályozásunk fázistartalékát csökkentette, így a kocsi nagy sebességeken irányíthatatlanná vált volna. Ha gyorsak akartunk lenni, akkor kellett egy stabil váz.
A vonalérzékelésre már adott volt tavalyról két vonalszenzor. Ezeknek fix magasság kellett az optimális működéshez. Emiatt lengéscsillapítókra nem volt szükség. Végül a kocsiból csak a hajtásláncot hagytuk meg. Másik határfeltétel volt az adott alaplemez használata, ugyanis erre kerül a kameratartó állvány és a szponzor logók. Az alvázat Hava (Dávid) tervezte Fusion 360 segítségével, figyelembe véve a furatok helyeit és az adott hajtásláncot; nem utolsó sorban az ütközések esetén fellépő erőket. A vázat a SEM-ben martuk ki a CNC marógépen. Sajnos a jelenlegi technológia alumínium megmunkálásra még nincs teljesen kidolgozva, így több marófej is életét vesztette a megmunkálás folyamán. Természetesen a fejlesztést nem aluból kezdtük, több farostlemez modell előzte meg a végleges kialakítást. Az eredmények beszéljenek magukért:
Egyéb módosítások:
A stabil kormányzásért volt még felelős a forgó alkatrészek csapágyazása. Minden kotyogást és holtjátékot szerettünk volna kiiktatni, ami a rendszerünk dinamikus viselkedését rontotta volna. A csapágyakat HDD meghajtókból bontottuk. Ebből került 6 darab a kormányműbe. A szervót cseréltük egy gyorsabbra és módosítottuk az elhelyezését (a tengelyhez közelebb helyeztük el) hogy a súlyközéppontot középen tartsuk és az erőkarok rövidebbek legyenek és kisebb legyen az áttétel. A kormányművet valamint a sebesség és pozícióméréshez szükséges alkatrészeket AutoCAD-ben terveztem, és a műhely 3D nyomtatóján keltettük életre.
Egyéb módosításokra is szükség volt. Az első kerekek felfüggesztését egy csavarral szerettük volna megoldani. Így (minimálisan) állítható lett volna a kerékmagasság, amivel a vonalszenzort tudtuk volna finomhangolni. Az első ötletünk, hogy a Schönherz Mátrixnál alkalmazott bronz csavarbetétekkel dolgozunk, ez azonban a sorozatos ütközések miatt nem bírta az idénybevételt és gyakran kiszakadt. A végleges megoldásunk egy M3-as betétes anyacsavar (rezgések miatt nem lazul így ki, mivel van benne egy műanyag gyűrű) lett, amit belül helyeztünk el, így a rögzítő csavarok kifele feszítették.
Másik probléma volt a kerekek lötyögése a csapágyházban. Ez egyrészt a laza csapágyak miatt volt, amin nem tudtunk változtatni. Nem akartunk még új csapágyakat is beszerezni. A másik oka a jelenségnek, hogy a csapágyak felfekvési felülete teljesen sík volt, így a belső gyűrű nekifeszült a csapágyháznak és erősen súrlódott. Ami egyrészt azért probléma, mert a nyomatékunk elveszik, másrészről nem egyenletesen terheli a kerekeket, a differenciálmű nem tudja elosztani a terhelést. Ez a súrlódás a kerékcsavar meghúzásakor jelentkezett. Ezt a problémát és a lötyögést egyszerre orvosolta egy nyomtatott távtartó gyűrű ami a csapágyak külső gyűrűjére feküdt fel, így a belső gyűrű még feszítés esetén sem érte el a csapágyház oldalát, ezért egy jól meghúzott kerékcsavar megfeszítette a csapágyat és ezért nem tudott lötyögni. Sajnos erről nincs képünk, de ilyen gyűrűket kapott az Override csapat is 🙂
Végül még egy ötletünk felmerült a pályán maradásra. Ez pedig a tapadási súrlódás növelése volt, amit hagyományosan gumikesztyűkkel próbálnak több-kevesebb sikerrel orvosolni a csapatok. Mi azt találtuk ki, hogy saját kerekeket csinálunk. A gumit pedig egy jól tapadó gumival oldottuk volna meg, specifikusan FBS szilikonnal. A felniket egy interneten talált modell alapján módosítottuk. Mivel ez STL formátumban volt elérhető, így ezt 3ds Max programmal átrajzoltam, hogy kompatibilis legyen a kocsival és a mérete is megfelelő legyen (átmérő és szélesség). A nyomtató hetekig tartó finomhangolása után a 3D nyomtatónkon keltettük életre. A gumi öntését eredetileg egy PS (polisztirol) habból mart öntőformával oldottuk volna meg, a száradást követően pedig acetonnal (dimetil-keton) távolítottuk volna el a PS habot. Sajnos a használt PS hab pórusai túl nagyok voltak, így a gumi felülete ‘szőrös’ lett. Több szerencsénk lett volna egy nagyobb sűrűségű habbal. Második nekifutásra inkább az öntőformát is nyomtattuk. Itt sajnos a pórusok hiánya miatt nem jutott elég vízpára a szilikon megkötéséhez (ecetsavas szilikon), ezért ez a folyamat több mint egy hetet váratott magára. Végül a forma eltávolítását csak egy hőlégfúvóval tudtuk megoldani, mivel a gumi remekül megfogta a műanyagunkat (PLA). Egyéb dolog amire figyelni kellett, hogy az öntőforma megtartsa a kerek alakját, amit a CNC-n mart rétegelt lemez tartószerkezettel értük el. Ennek hiányában a gumi excentrikus lett volna (így is az lett kicsit), ami miatt a kocsi pattogott volna menet közben. Végül mikor készen lettünk ezzel, a félelmeink beigazolódtak. Az alternatív gumikesztyűs megoldás jobbnak bizonyult, mivel a kerék nehéz volt, nem tapadt olyan jól, mint reméltük, és excentrikussága miatt nagyobb sebesség esetén pattogni kezdett, amitől a vonalszenzor elvesztette a fonalat.
Elektromos változtatások:
Szerencsére a tavalyi versenyre egészen jó elektronika sikerült, így ezen lényeges változtatást nem kellett végrehajtsunk. A munka nagyja kimerült az elektronika elhelyezésén az új vázon. Itt mindent a tengelyhez lehető legközelebb helyeztünk el. Az akkumulátort Li-Po cellákra cseréltük (Ni-MH ról), így, hála a kiváló MOS-FET-eknek a motor csúcsáramban akár 200A-t is fel tudott venni. A Li-Po cellákat a váz oldalán egy tépőzárral rögzítettük. Az új szervó kihajtása érdekében a tápfeszültségét 6V-ról 7.4V-ra növeltük, ami a meglévő kapcsolóüzemű tápegységben csak egy ellenállás cseréjével járt. Emellé még szükség volt egy nagy kapacitás beszerelése, mivel a szervó maximális árama meghaladta a tápegység terhelhetőségét. Ezt végül 2x4700uF beiktatásával kiküszöböltük. A munka nagyobb részét az igényes kábelelvezetés tette ki, mivel nem használtunk buszrendszert. A vezetékeket zsugorcsövekben vezettük el, így esztétikusan minden fekete volt és a zsugorcső megtartotta a formáját, a vezetékek nem mászkáltak el. Ezek mellett tucatnyi fekete gyorskötöző rögzítette a fontosabb vezetékeket.
A szoftver:
A tavalyi szoftver alapjaiban még használhatónak bizonyult, bár meglehetősen sok utómunkát igényelt. Ez szinte kizárólag Hava érdeme. Az egész kocsi lelke egy STM32 Nucleo (F4-es széria) fejlesztőpanel, ami egy processzormaggal 180MHz-es órajelen ketyeg (üzenném a kollégáknak, nem 16MHz-en). Tömören egy számláló interrupt adja a task-ok ütemezését, amit időben eltolva futtatunk. Ezek a task-ok felelnek a szenzorok jeleinek bekéréséért, a szabályozók futtatásáért és időzítéséért, a kommunikációért és a versenyhez szükséges állapotgépek működéséért.
Ezen a ponton egészíteném ki Benjamin barátom szavait. A tavalyi szoftver ugyan nagyon magas szintet elért, hiszen képes volt minden olyan működés megvalósítására, mely azon a versenyen elvárás lett volna (a sikeres Q1, Q2, Q3 kvalifikációk is ezt támasztják alá.) Mindazonáltal míg tavaly nagyon sok energiát fordítottunk az elektronika kivitelezésére, a szoftver elkészítése korántsem ment zökkenőmentesen. Ugyan git verziókövető szoftvert már akkor is használtunk a fejlesztés során, de nem ismertük az online együtt dolgozásban nyújtott lehetőségeit. A fejlesztés nagyrészt egy szálon futott és az aktuális verziókat egymásnak adogattuk át, esetleg együtt fűztük össze. Ez egy követhetetlen fejlesztéshez és egy gyorsan rohadó kód létrehozásához vezetett. Az elkészült verzió nem volt sem moduláris sem továbbfejleszthető. A versenyt megelőzőleg megközelítőleg két hónapot öltem a kód strukturálásába és moduláris átalakításába, ezt követően kezdődhetett meg a közös fejlesztés. Ezúttal a gitlab minden online fejlesztési lehetőségét felhasználtuk és hatékonyan több szálon fejlesztettük tovább a kódot. Annak jelenlegi felépítése és követhetősége szerény véleményem szerint példaértékű és jól példázza a közös fejlesztésekben rejlő lehetőségek tárházát.
Fejlesztőkörnyezet, HIL szimuláció:
A szoftverünk alapját az STM32 cubeMX konfigurációs szoftvere adta. STM esetén a lábak kiosztása és perifériák működési módjai konfigurációfüggőek, tehát a cubeMX fájlt érdemes a hardvertervezés előtt létrehozni. A kód fordítását True Studioban (Atollic) végeztük azonban annak betegségeit kikerülve a kódírásra különböző okos szövegszerkesztőket használtunk (pl.: Visual Studio Code). A szoftver hardvervezérlő részeinek kipróbálása főleg a nagyáramú részeken nagy veszélyeket rejtett magában ezért belső szabályzóinkat gyakran MATLAB vagy HIL szimulációs környezetben teszteltük. A kódot a GITLAB segítségével verziókövettük.
A működéshez szükséges szabályozási algoritmusok:
Az autóban a legkülönfélébb szabályzási körök és algoritmusok kaptak helyet. Az elsődleges feladat a jármű vonalkövetése volt, azonban ennek megvalósítása korántsem triviális feladat. A kormányszabályozás hibajelét a vonalszenzorok adataiból nyerhettük. Két vonalszenzort használva lehetőségünk nyílt a pozícióadatokon kívül odometriai adatok kinyerésére is (a jármű vonalhoz képest vett helyzete). Ebben az esetben állapotteres szabályozót használhattunk volna a feladat megvalósítására. A tavalyi évben megépített vonalszenzoraink tökéletesen működtek, azonban hosszas megfontolások után úgy véltük az odometriai adatok nem nyújtanának annyi plusz információt számunkra, hogy releváns döntés legyen a két vonalszenzor együttes használata. A verseny során tehát egy vonalszenzort használtunk. Nem mellesleg, mivel az elsődleges szenzor az autó elején foglal helyet, így potenciálisan több sérülésnek van kitéve, így jobb, ha van egy pótszenzor, ha bármi történne.
Ebben az esetben a vonal szögét nem ismerjük, kizárólag egy becslő adatunk van a vonal járműhöz viszonyított szögéről. Ismerjük viszont azon távolságot, mely a kormányzott kerekek tengelye és a vonalszenzor érzékelési vonala között helyezkedik el. Pontos hibajelet ezáltal nem tudunk előállítani a szabályozónk számára, további elhanyagolásokkal kell élnünk. Feltételeztük, hogy a vonal a járművünk közepe alatt fekszik és annak irányának változása során sem hajtunk le róla. Ebben az esetben a hibaszög becslésére jó algoritmus lehet a kormányzott kerek tengelyének középpontja és a vonalszenzor által érzékel pont által meghatározott szög használata. A kormányszabályozást egy PD szabályozóval valósítottuk meg. Ezen szabályozó egy arányos és egy differenciáló tagból épül fel. A valós autó során a PID szabályozó I (integráló) tagját a kormányszervó alkotja, hiszen az ugrásszerű beavarozójelre nem tud végtelen gyors változást előidézni a kormányszögben. A szabályozó paraméterei azonban nem fixek. Észre kell vennünk, hogy nagy sebesség esetén gyors beállást elősegítendő nagy P tag és a kis D tag mely csökkenti a hibajelek szűrését azonnali kisodródáshoz vezetne. A szabályozó paramétereit tehát sebességfüggően váltani / interpolálni kellett. Mi az előbbi módszert választottuk.
Sebességszabályozás:
A versenyfelkészülés során az induló csapatoknak több egyedi döntést meg kell hozniuk. Ezen elkerülhetetlen és fontos döntések közé tartozik, hogy építenek-e saját motorvezérlőt, vagy használják a RC kocsival együtt kapott gyári változatot. Az AUT tanszék a versenyzők felkészítése érdekében szemináriumokat szervez, melyen ismerteti, miként érdemes az autó HW és szoftverelemeit elkészíteni, A motorvezérlő szeminárium megmutatja a gyári motorvezérlő használatának hátrányit és lehetőséget nyújt egy jól átgondolt saját darab elkészítésére.
A verseny során szükségünk van az autó sebességének mindenkori ismeretére és annak pontos beállítására. Ezt a feladatot nehezíti a gyorsasági pályán lévő nagy szintkülönbség. Az autó lefelé menet fékezés és megfelelő vezérlés hiányában meglódulhat, továbbá a váratlan sebességváltozás a kormányszabályozó algoritmusát is instabil szabályozási tartományba kényszerítheti. Ezen a ponton az autó elveszítheti a vonalat és nagy sebességgel a szemközti falon találhatja magát.
A gyári motorvezérlő esetén az egyetlen lehetőség az alábbi hibák kivédésére a motorvezérlő mint fekete doboz identifikálása. Ebben az esetben egy PI fordulatszám-szabályozás valósítható meg. Azonban nem szabad elfelejteni a gyári motorvezérlő felépítéséből adódó korlátokat. Felépítése nem teszi lehetővé a lassú menetet, az azonnali forgásirány váltást és a fékezést sem. Továbbá gondot jelent a nem szimmetrikusan kialakított vezérlési tartománya (előremenetben meglódul és nem lehet lassan menni vele) és korlátozott áramtűrése is. A kisfrekvenciás működéséből adódó sípolásról pedig ne is beszéljünk. 😀
Egy egyedi motorvezérlő esetén lehetőségünk van egy kétkörös, belső áram, külső fordulatszám szabályzó (kaszkád szabályozás) megvalósítására. Az egyedi H híd és annak vezérlése lehetőséget nyújt a motorfék létrehozására, mely működéséből adódóan a maximális fékerőt biztosítja a kocsi megcsúszása nélkül. (amennyiben a kerekek megcsúsznak csökken az indukált áram mellyel arányosan csökken a fékerő is) Az egyedi felépítés nagyon pontos és dinamikus sebességszabályozást tesz lehetővé az eredeti motorvezérlő által elképzelhetetlen működési frekvencián és áramokon.
A vonalszenzor:
A hardvert készen kaptam, de a hozott kódot nagyjából újra kellett írnom, miután a működését visszafejtettem a tervek és a régi kódok alapján. A szenzor feladata, hogy az 1-2 cm-re levő szigetelőszalag csík pozícióját megadja. Ezt rendhagyó módon 48 infra szenzorral lett megoldva, amivel a térbeli felbontásunk jobb lett az átlagosnál, kicsit szélesebb vonalszakaszon érzékelt és az eltolt kiolvasás miatt az időbeli felbontásunk is 1-2 ms-ra redukálódott. Ebből azonban a kocsi beavatkozóinak lassúsága miatt csak 10ms-onként vettünk mintát. A hardver röviden:
A 48 ledet 6 darab STP08CP05 LED-meghajtó IC valósítja meg, ami 30mA áramot enged át a TCRT5000-es szenzorokon. Ezzel a talaj 1-2 cm-re pont optimálisan van megvilágítva a LED-ek nyílásszöge miatt, nagyobb áram esetén beég a kép és a szenzorok között kezelhetetlen lesz az áthallás kisebb áram esetén pedig bizonytalan lesz a vonal pozíciómeghatározása. A 48 infra fototranzisztor jeleit ugyancsak 6 darab analóg multiplexer viszi a központi mikrovezérlőhöz (STM32F303K), ahol a beépített két analóg-digitális átalakító 3-3 csatornán mintavételezi a fototranzisztorok jeleit. A LED-ek felvillantását eltolva oldjuk meg, tehát egy ciklusban minden 8. led világít és 6 analóg adatunk adódik. A 8. ciklus után kapjuk a teljes látott vonal értékeit.
Szoftveres oldalról a vonalból nekünk csak azok pozíciói érdekesek. Egy tömbben tároljuk az egyes LED-ek pozícióját, amit (leegyszerűsítve) súlyozzuk a mért adatainkkal. Itt sokat segített a vonalfelismerés írásában, hogy korábban volt szerencsém résztvenni az egyetemi lézerszkenneres projektben, ahova írtam egy hasonló vonalfelismerő algoritmust.
Egyéb funkciókkal is bővült a vonalszenzor szoftvere: Állítható lett a mintavételi idő, 10-re növeltem a látott vonalak maximális számát (többet nemigen tudna érzékelni a felbontás miatt), lehetett kalibrálni a LED-eket (maximális és minimális érzékelt fényerő -> mért értékek átskálázása), a kalibrációt menteni a lokális FLASH-be (mivel az STM-ben nem volt dedikált EEPROM). A vonalérzékelésen még finomítani kellett a felbontást ezért egy nemlineáris szűrőt is beiktattam a képfeldolgozásba, ami kiemelte a csúcsértékeket. Erre azért volt szükség, mivel egy egyszerű treshold alkalmazása esetén két közeli vonal között van áthallás tértartományban, így előfordult hogy két vonalat egyben érzékelt, ami miatt a vonaljelzések felismerése megbízhatatlanul működött. A szűrővel az érzékelt kép stabilnak bizonyult, többet semmi panaszunk nem volt rá.
Vonal alakzatok felismerése:
A másik feladatom volt a vonalszenzor adatait értelmes jelzésekké alakítani. A gyorsító szakaszt, lassító szakasz elejét és végét felismerni, a elágazásokat (és azon belül egy elágazásba melyik kapun léptünk be) és nem utolsó sorban az ügyességi pályának a kilépő kapuját (melyik oldalt milyen irányban kell lehajtani). A feladat nem tűnt kifejezetten egyszerűnek, de kis gondolkodás után mégis meglehetősen egyszerűre redukálódott. Az algoritmus bemenetei az aktuálisan látott vonalak száma, pozíciója és a kocsi pozíciója (a start óta megtett mm-ek). Azonban a pozícióadatokra általában nem volt szükség, csak elágazások és az ügyességi pálya kijárata esetén. Ezt egy állapotgép dolgozta fel, aminek a feladata a látott vonalak számának a figyelése és azok maximumának eltárolása. Amikor a látott vonalak száma 1-re csökkent, akkor kiértékelte a látottakat. Röviden összefoglalva:
-maximum keresése
-ha vonalszám nőtt, akkor elindít egy számlálót (megtett mm) -> ha a vonaltáv < treshold
-ha a vonalszám 1-re csökkent, akkor kiértékeljük és újraindítjuk az állapotgépet
-ha a számláló lejárt kiértékeljük -> lassító szakasz eleje vagy elágazás
Persze ez nem tűnt mindig ennyire egyszerűnek, amihez hozzájárult a vonalszenzor hibája is. Például szenzor szélein a környezeti fény megvilágította a szélső érzékelőt, ami előfeszítette az érzékelőt és kanyarban picit megemelkedve (a centrifugális erő miatt) a szenzor jelzett, ezért a vonalszám megugrott és a kocsi elvétette az elágazás kapuját (rossz eredményt adott). Az ilyen hibákat a kommunikációs modul miatt gyorsan tudtuk észlelni és kezelni.
A vonal követését egyszerűen mindig a korábbihoz közelebb eső vonallal oldottuk meg. A sávváltás (ha C kapun mentünk be egy elágazásba) csak egy függvényhívás volt így. Másrészt így nem jelentkezett az a hatás, amit több csapatnál is megfigyeltünk, hogy két vonal esetén a szabályozás megrándul, mivel nem érzékeli külön a vonalakat.
Útvonaltervezés:
Ez volt az idei verseny igazi feladata. Egy ismeretlen labirintust kellett feltérképezni, azáltal, hogy bejártuk (legalább) egyszer a pálya minden útját. A bejárást egy, a pályaszakaszon elhelyezett kapu jelezte. Hogy ne legyen olyan egyszerű a feladat, minden kapu +15mp menetidőt adott, a startkapun áthaladás 20mp időt adott az első kapuig. Szerencsére elég kicsi volt a pálya, a kocsi meg elég gyors. A nagyobb feladat egy navigációs célokra megfelelő térkép felépítése. Itt nem használhattuk az egyszerű gráfokat, sem irányított gráfokat, mivel a kapuk csak egyik irányba működnek, más szakaszról érkezve tulajdonképpen nem is tekinthetők elágazásnak. A másik probléma, amit működőképes formába sajnos nem sikerült önteni, a helymeghatározás, vagyis annak a problémája, hogy bármely pontján a pályának megmondhassuk, hogy melyik szakaszon vagy elágazásban vagyunk, és hogy voltunk-e már itt vagy merre menjünk, ahol még nem voltunk.
Mivel GPS-t sem más vezeték nélküli kommunikációs technológiát nem használhattunk, így első próbálkozásunkkal egy IMU szenzorral (gyorsulásmérő és giroszkóp) próbálkoztunk a pályát rekonstruálni. Ezt többnyire sikerült is megtenni, de ehhez minden út előtt kalibrálni kellett a szenzorunkat, és rendszerint egy kör után így is 10-15 cm-t tévedett. Ezt egy kalibrációs függvénnyel esetleg meg lehetett volna gyógyítani, de így is csak a mi csapatunk tudott értelmes pályaadatokat kicsiszolni a szenzor adataiból (létezik pontosabb szenzor is, meg jobb kalibrálás is).
Maga a pálya gráfjának építése bonyolultabb annál, hogy itt részletezzem, de röviden összefoglalva a térképező algoritmus a vonalszenzor eseményeiből és pozícióadatokból (encoder, IMU) rögzíti a csomópontok 2d pozícióját, és a csomópontokat összekötő kapukat. Egy csomópont A, B és C kapuból áll. C kapun bemenve lehet A vagy B kapun kimenni, az A kapu esetén maradunk a vonalon, B kapu esetén leágazunk. A vagy B kapunk behajtva egy csomópontba csak C kapun mehetünk ki. Az algoritmus egy adatbázist épít folyamatosan, eltárolja, hogy egyik csomópont kapujából melyik csomópont kapujába érkezünk (és hogy mekkora a kapuk távolságuk). Ezek mellett természetesen ha megtalálja a kilépési pontot, annak a helyzetét is eltárolja, mint csomópont, így a pálya feltérképezése után megtervezheti a kilépéshez szükséges útvonalat.
Maga a feltérképező rész csak egy ismeretlen csomópontba érkezés esetén hívódik meg. Egyébként a már meglévő térképen navigál az algoritmus, vagyis egy útvonalat tervez a legközelebbi még ismeretlen szakaszig (az a kapu amelynek a kilépési kapuja nem tudjuk hova vezet) vagy ha minden kapu ismert, akkor a kilépési pontig. Mivel a versenykiírásban kevesebb, mint 20 kapu volt, így teljesen élhető algoritmus, hogy sorba menve megnézzük az összes lehetséges útvonalat, a legrövidebbtől haladva a leghosszabb fele. Ehhez jön az egyszerűsítés, hogy a legtöbb kapu esetén úgysem lehet leágazni. Az útvonalat a jelenlegi csomópontból kiindulva egy bináris számmal kódolom, ahol az egyes bitek azt jelölik, hogy az adott csomópontból számítva az n. csomópontban leágazzunk-e vagy sem. A tervező algoritmus rendre megvizsgálta a 1, 2, 3 hosszú útvonalakat és ha egy útvonal egy ismeretlen szakaszra vezet vagy adott esetben ki a labirintusból, akkor rábólintott, és csak végigment rajta.
Sajnos mint említettem a giroszkóp megbízhatatlansága miatt az utolsó este kukába kellett dobni az algoritmust, mivel a kulcsfontosságú lokalizáció lábait kirúgta a giroszkóp. Ekkor volt olyan hajnali 1-2 óra. Ki kellett találni valami egészen mást, amihez nem kell giroszkóp, de legalább is elég ha pontatlan. Sajnos a szakaszokon nem lehetett a giroszkóp hibáját kiküszöbölni, mivel nem minden szakasz orientációja 90° egész számú többszöröse. Egyik fontos megjegyzés, hogy a csomópontok 90°-onként vannak forgatva, tehát minden csomópontban ismert az abszolút orientáció, ráadásul 45°os hibahatáron bőven belül van a giroszkóp pontossága. Pár órás kétségbeesést és pánikot követően végül rájöttem, hogy egy orientációból, előző csomóponthoz képest elfordulásból (szumma + vagy – irány elég) és az előző szakasz hosszából is egyértelműen azonosítható egy szakasz végpontja (csomópont). Mire ezt lekódoltam lehetett nagyjából reggeli 6-7 óra. Sajnos egy hetes éjszakázás és lassan 24 órás ébrenlét után sok hibával kódolok, így a lekódolt megoldásom is hintve volt hibával, állapotgépeket teszteltem egy rögtönzött virtuális környezetben, de sajnos nem úgy tűnt, hogy aznap még működni fog, így biztosra mentünk, és egy robosztus, ám annál letisztultabb függvényt tettünk meg kormányosunknak, a jó öreg rand() függvényt. Mint a verseny mutatja, hála a jó alapnak ez tényleg csak egy függvényhívásból állt, és egész szép eredményt ért el. Az Y kanyarért hála Hava előrelátó kódolásának és az eltévedt kocsinak. Ezt mindenképpen ki akartuk próbálni 😀
Kommunikáció:
A kommunikációért és a szabályozók hangolásáért a bluetooth modul volt a felelős. Ezt például telefonról tudtuk kezelni. Maga a modul egy mezei HC-05-ös bluetooth modul volt, amit soros porton értünk el és maga az eszköz telefon oldalról egy terminálként üzemelt. A kocsi paramétereinek hangolását szöveges parancsokkal tudtuk hangolni. Ez kapóra jött a kormányzás PD szabályozójának hangolásához különböző sebességek mellett (mivel a PID szabályozók sebességfüggőek, ezért is lett volna jobb az állapotteres megoldás). Ezekkel tudtunk minden paramétert behangolni, mint a sebességeket, a hozzájuk tartozó szabályozó paramétereket valós időben, féktávokat, gyorsulási paramétereket minden körre vagy esetleg az állapotgépeket léptetni a hibakereséshez. Különösen a hibakeresésben volt hasznos, hogy valós időben volt egy felület, ahova valós időben írathattuk a hibaüzeneteket, szenzoradatokat vagy már beállított paramétereket.
Ezt a programot használtuk (Android): link
A program nagy előnye, hogy könnyen és gyorsan tudunk csatlakozni az eszközre (sokszor indul újra az eszköz fejlesztés közben) valamint rengeteg makrogombot lehet hozzáadni, ami megkönnyíti a kommunikációt.
Törések:
Nyilván mi sem úsztuk meg a teszteket törések nélkül. Ahogy Ben bácsi modta az ifjú Peter Parker-nek: a nagyobb nyomaték nagyobb ütközésekkel jár. Ez nálunk sem volt máshogy:
A verseny:
A versenyfelvételért a Budavári Schönherz Stúdiónak jár a köszönet. (1:08:00-tól)
https://bsstudio.hu/video/robonaut-2019-kozvetites
Sajnos a lassúságunk miatt csak a 2. helyezésre futotta. Bár meg vagyunk győződve róla, hogy ha több időt hagynak a gyors szakasz finomhangolására, akkor nagyobb sebességeket is elérhettünk volna. Habár a közönségdíjhoz egy csinos kasztni sem ártott volna.
Mindez összejött a Faketelen Taxi csapatának, dacára hogy az utolsó éjjel leégett a motorjuk, és így egy hangolatlan kocsival értek el rekordsebességet.
Ezennel itt is gratulálunk kiváló eredményeikhez!
Kasztni:
Mit a kedves kommentátor megjegyezte, a Tesla az esztétikára is nagy hangsúlyt fektet. Ez nálunk is meglett volna, de a prioritások miatt ez már nem készült el a versenyre (sőt azóta sem). De amint lesz újra nyomtatónk ez sem marad befejezetlenül. Pár látványterv azért van:
Végül szeretnék köszönetet mondani elsősorban csapattársaimnak:
Havasi Dávidnak és Domonkos Albrecht-nek a közös munkáért és a rengetek élményért, másodsorban minden barátnak és ismerősnek, akik ott voltak a versenyen vagy követték a közvetítést.