Robotkéz Készítő: Kiss Ádám Évfolyam: 9. Iskola: Bányai Júlia Gimnázium, 6000 Kecskemét, nyíri u. 11. E-mail: adamantan@gmail.com A konstrukció általános bemutatása A cél egy olyan robotkonstrukció építése volt, amely működését tekintve egy emberi kéz mozgását képes szimulálni. Tehát öt ujj helyezkedik el egy kézfejen, minden ujj három-három mozgatható ujjpercet tartalmaz (kivéve a nagyujjat, ahol csak kettő van). A kéz ujjai külön-külön mozgathatók. Ujjanként egy-egy ütközésérzékelő benyomása, illetve felengedése vezérli az ujj behajlítását és kiegyenesítését, az emberi kéz mozgásához hasonlóan. Ujjpercek Inak Az ujjakat mozgató szervomotorok NXT vezérlőegységek A megvalósítás eszközeként a LEGO cég által kifejlesztett Mindstorms NXT 2.0-ás robotot használtam. - 1 -
A konstrukció technikai részletei Minden ujjat (öt darab) külön szervo motor vezérel. Az ujj behajlítását és kiegyenesítését is ugyanaz a motor végzi. Ezért olyan eszközre volt szükség, amely a biológiai ínszalagok szerepét átveszi, de kellően merev ahhoz, hogy a kiegyenesítési funkciót is végrehajtsa. A robotkéz kutatásokban pl. hajlékony kevlár szálakat használnak erre a célra, amelyek kellően rugalmasak és erősek. Ilyen esetekben a behajlításhoz és kiegyenesítéshez több ínszalag és több szervo motor szükséges. Ideális esetben a kéz szabadsági fokainak megfelelő számú (igen sok). Mivel egy darab Mindstorms NXT téglára összesen három szervo motor kapcsolható, ezért két darab téglát használtam és ujjanként egy-egy motort. A kétféle irányú ujjmozgás megvalósításához műanyag bilincseket választottam, amelyek átveszik az ínszalagok szerepét. Ezek fogazása alkalmas arra, hogy a motorokra szerelt fogaskerekek a mechanikai áttételt megvalósítsák és a motor körkörös mozgását egyenes irányú mozgássá alakítsák. A két darab NXT tégla egymástól függetlenül működteti a motorokat. Az egyik tégla a 2-4. ujjakat (a három középső ujj), míg a másik tégla az 1. és 5. ujjat (kisujj és hüvelykujj). A behajlításkor a tengelyekkel rögzített ujjpercek elfordulnak a tengely mentén a megfeszített ínszalag hatására, míg a kiegyenesítéskor a merev műanyag az eredeti állapotba fordítja vissza őket. - 2 -
Az ujjpercek hosszának arányai nem teljesítik a kéz biológiai Fibonacci számok szerinti arányait, a LEGO elemek adott méretkorlátai miatt. A hüvelykujj elhelyezése eltér a többitől. Az emberi kéz mintájára ez részben szembefordítható a többivel, így a kéz alkalmas könnyű tárgyak megfogására és tartására. Ujjpercek Inak Az ujjakat mozgató szervomotorok NXT vezérlőegységek A hüvelykujjat mozgató motor és a műanyag bilincs közel merőlegesen helyezkedik el a többihez képest. - 3 -
Az emberi kéz és az elkészített robotkéz arányait szemlélteti a következő ábra. A piros vonalak az ujjak elhelyezkedését mutatják a robotkézen és egy emberi kézen. Az ujjakat öt darab ütközésérzékelővel lehet irányítani (ujjanként eggyel). Ezek az NXT téglák bemeneti portjaihoz RCX robotkábelekkel csatlakoznak, mivel a szabványos NXT kábeleknek nem megfelelő a hosszuk. Az ütközésérzékelők a könnyebb használhatóság miatt egy kézre szerelhető kesztyű -re rögzítve kaptak helyet. - 4 -
A vezérlő program A robotkezet vezérlő program NXC nyelven készült (a robothoz fejlesztett C szerű programnyelv). A konstrukcióhoz használt két Mindstorms NXT téglán ugyanaz a program fut, de a téglák nem kommunikálnak egymással, az algoritmusaik működése független egymástól. Egy-egy ütközésérzékelő vezérli a szervomotorokat. Benyomott állapotban a motorok bekapcsolnak és a fogaskerék áttétel segítségével feszítik a műanyag bilincseket, aminek következtében a vezérelt ujj a ujjperctengelyek mentén behajlik. Ha az ínszalag szerepét betöltő huzal feszítése mindaddig történne, amíg az ütközésérzékelő be van nyomva, akkor a hajlítás könnyen túlfeszülést eredményezhetne. Ezért a vezérlő algoritmus tartalmaz egy motorelfordulási szög szerinti korlátozást. Az adott elfordulási szöget elérve a motor működése leáll, függetlenül az ütközésérzékelő állapotától. Ez a korlát 200 o. Tehát ha a motor elérte a 200 o -os elfordulást, akkor leáll. Kiegyenesítésnél a motor ellenkező irányban forog mindaddig, amíg az ütközésérzékelő felengedett állapotban van és az elfordulási szög vissza nem áll a nulla fokra. Az ujjakat egymással párhuzamosan lehet működtetni. Ehhez külön taszkban (szálon) helyeztem el ugyanazokat a vezérlő szerkezeteket. Az NXT tégla alkalmas arra, hogy párhuzamos programszálon elhelyezett utasításokat látszólag egy időben hajtson végre. Ezzel elérhető, hogy az ujjak egymástól függetlenül, egyszerre működjenek. Ha egy ujjat vezérlő ütközésérzékelő benyomva tartása kevesebb ideig tart, mint a 200 o -os elfordulás, akkor a végtelen ciklus használata miatt nem hajlik be teljesen és a kiegyenesítés sem eredményez túlzott visszafordítást, hiszen a nulla fokos elfordulási szögig tart a visszafelé mozgás. A program megírása során ügyelni kellett arra, hogy a motorok helytakarékosság szempontjából az egyes ujjaknál fordítva lettek beszerelve (három motor egyirányú, két motor fordított irányú), így az elfordulási szögek előjele is eltért a két különböző esetben. A vezérlést végző algoritmusnál ezt figyelembe kellett venni. A motor forgásirányát a sebességparaméterének előjelével is tudjuk szabályozni, így ezt használtam ki a programban. Törekedtem arra, hogy a lehető legáltalánosabb (legkevesebb konstanst) használó programot készítsek, így minden ujj vezérlését ugyanaz az algoritmusszerkezet végzi, függetlenül a motor és az ütközésérzékelő csatlakozási portjától és a forgásiránytól. Az eltérő értékeket paraméterként kapják meg a vezérlési szerkezetek. Az algoritmus forráskódját több részletben mutatom be. A program fejléce Egy ujj vezérlését megvalósító taszk (programszál) A SEB konstans a motorok forgási sebességét tartalmazza. Ez 1-100 közötti szám lehet. A SZOG konstans a maximális motortengely elfordulási szöget (korlátot) jelenti. A második ujj (gyűrűs) vezérlését megvalósító programszál példáját mutatom be. - 5 -
Minden taszk két belső változót tartalmaz (melyik és merre). Sajnos az NXC nyelvben nincs lehetőségünk paraméterek átadására a taszkoknak külső forrásból, csak globális változókon keresztül, de ezekre most nem volt szükség. A melyik változó a motor, és ütközésérzékelő csatlakozási portját határozza meg. Jelen esetben ez a 0, így az A portra kötött motor és az 1-es portra kötött ütközésérzékelőt azonosítja. A többi taszk (a többi ujj) esetén, ezek rendre 1 (B motorport és 2-es input port) illetve 2 (C motorport és 3-as input port). A merre változó a motorok forgásirányát szabályozza. Ha az értéke 1, akkor előre forog a motor, ha 1, akkor hátra. A SetSensorTouch() függvény az ütközésérzékelőt inicializálja. A ResetRotationCount() függvény a motor aktuális elfordulási szög értékét nullázza le. Ha nem nulláznánk le, akkor az elfordulási korlátként beállított 200 o -os szöget nem tudnánk garantálni. Az előkészítés után indul a végtelen ciklus (while (true)), amely biztosítja a folyamatos figyelést és működést. A ciklusban egyetlen összetett utasítás szerepel. Az első elágazás (if) vezérli a behajlítást. Ha az ütközésérzékelő be van nyomva (Sensor()==1) és a motor elfordulási szöge 200 o -nál kisebb (MotorRotationCount()<SZOG), akkor bekapcsolja a motor előre forgatását (OnFwd()). A forgásirányt a merre*seb előjele határozza meg. Ha ez pozitív, akkor előre történik a forgatás, egyébként hátra. A forgási sebesség mindkét esetben ugyanakkora (SEB). A feltételben használt abs() (abszolútérték) függvény garantálja, hogy ellentétes irányban történő forgatás esetén is a +200 o -os korlátot tudjuk használni (egyébként az elfordulási szög lehetne negatív is a motor forgásirányától függően). Az elágazás egyébként ága (else) vezérli a kiegyenesítést. Egy újabb elágazás vizsgálja azt a feltételt, hogy az ütközésérzékelő kiengedett állapotú-e (Sensor()==0), és a motor elfordulási szöge (merre*motorrotationcount()>0) visszaért-e a kiinduló állapotba. A merre változóval történő szorzás szintén az előjel miatt szükséges. Ha a feltétel teljesül, akkor a motort ellenkező irányba forgatjuk (OnRev()). A paraméterezés megegyezik a korábban ismertetettel. Ha egyik feltétel sem teljesül, akkor a motorokat kikapcsoljuk (Off()). Ezzel a feltételvezérléssel azt is elértem, hogy ha az ütközésérzékelőt hamarabb felengedjük, mint ahogy elérte volna a 200 o -ot, akkor elindul a visszaforgatás, illetve ha az ujj visszaállt az eredeti helyzetébe, de nem nyomjuk meg az ütközésérzékelőt, akkor nem indul el a motor, így nem hajlik az ujj sem. Valamennyi ujjat ugyanez az algoritmus vezérli, de a melyik és merre változóknak más a kezdőértéke. A harmadik ujj esetén: melyik = 1 merre = 1 A negyedik ujj esetén: melyik = 2 merre = 1 Az első ujj esetén (a 2. téglán futó programban): melyik = 0 merre = 1 Az ötödik ujj esetén (a 2. téglán futó programban): melyik = 2 merre = 1 A főprogram A főprogramban a taszkok indítása történik meg. Ezt a Precedes() függvényen keresztül lehet megtenni. Az 1- es tégla három középső ujjat vezérlő taszkjának a nevei: ujj2, ujj3, ujj4. - 6 -
A programot általánosabban is meg lehet írni. Mivel az egyes taszkok tartalma (a két-két paramétert kivéve) azonos, ezért célszerűnek tűnhet, hogy erre létrehozzunk egy saját függvényt és ezt hívjuk meg a taszkokon belül a megfelelő paraméterekkel. A program ebben az esetben nem működne helyesen, mivel a téglán a függvény egy adott memóriaterületen futna, akárhányszor hívnánk meg (rekurziót nem tud a firmware kezelni), így minden ujj ugyanazzal a paraméterrel működne a párhuzamos taszkok miatt. Általánosabb megoldást jelenthetne, ha a bemutatott közös kódrészletet, mint makrót készítjük el (ez szintén paraméterezhető), így már helyesen működő programkódhoz jutunk, de mivel az előfordító a makró kódrészletét beilleszti a forráskódba, így sokat nem nyernénk a programban. A makrók viszont egyetlen sornyi utasításból állhatnak csupán, így a túl hosszú sor miatt kevésbé lenne áttekinthető a program, de megoldható a programkonstrukció. - 7 -