Balansuojantis robotas

Važiuoti ant keturių ratų per daug paprasta. Ant dviejų daug sudėtingiau ir įdomiau. Balansuojantis robotas – nėra kažkas naujo. Principe tai tas pats, kas visiems žinomas SEGWAY, tik sumažintas variantas. Daug kas jį bandė padaryti, internete galima rasti nemažai video kaip jis veikia. Vieniems tai pavyko geriau, kitiems blogiau. Bet dalykas gana įdomus, labiausiai programine prasme. Pabandžiau ir aš tokį padaryti.

Ko reikia tokiam robotui?

Pirmiausiai reikalingi du varikliai su reduktoriais. Tokių variklių yra daugybė. Tik buvo neaišku, kokios apsukos reikalingos. Bandymui Ebay nusipirkau kelis paprasčiausius variklius, su plastmasiniais reduktoriais. Jie parduodami kartu su ratais. Vienas pliusas – jie pigūs. Bet, kaip paaiškėjo vėliau, kokybė pagal kainą… Dar kartu nusipirkau porą siaurų ratų, kurie tiko uždėti ant tokių reduktorių.

Dar reikia variklių draiverių. Tam panaudojau L293D. Jis gali valdyti du variklius. Varikliai ima apie 0,6A srovę kiekvienas. Tai šiek tiek per daug šiems draiveriams, bet, kaip paaiškėjo, dirba visai gerai, tiesa kaista stiprokai.

Dar reikia daviklių. Giroskopo ir dviejų akselerometrų. Mačiau, kad padaro su vienu akselerometru, bet geriau dėti du, nes naudojama ir Z ašis. Savo atsargose susiradau ADXR300 giroskopą ir du MMA2260D vienos ašies akselerometrus. Visi jie yra analoginiai. Galima būtų panaudoti ir kokius nors dabartinius daviklius, kur yra trys giroskopai, ir trys akselerometrai viename korpuse. Ir kainuoja toks daug pigiau. Bet naudojau tai kas buvo pas mane.

Dar reikia mikrokontrolerio. Panaudojau atmega328 su bootloaderiu. Principe tai galima vadinti Arduino, nes programai rašyti naudojau Arduino IDE.

Reikia ir akumuliatoriaus. Didelių srovių čia nėra, tinka bet koks, aš panaudojau 3 celių LiPo.

Ir paskutinis dalykas – reikia kažkur viską sudėt. Tam panaudojau kelis stiklo tekstolito gabalus ir kelis metalinius strypelius.

Surenkant yra daug neaiškų dalykų. Pvz. kur geriausia dėti daviklius? Man atrodė, kad logiškiausia būtų dėti apačioje, netoli ratų. Akumuliatorių uždėjau pačiam viršuje, nes maniau, kad taip turėtų būti lengviau balansuoti. Tačiau kokiame aukštyje būtų geriausia – irgi neaišku. O gal geriau kaip tik apačioje…

Varikliams reikia nuo 3V iki 6V. Kiek geriausia – neaišku. Pradžiai jų maitinimui panaudojau impulsinį BEC 5V. Jis gali duoti ir 6V. Ant variklių draiverių krinta apie 1,5V, taigi įtampa gavosi apie 4,5V.

Kad galima būtų balansuoti, reikia tiksliai žinoti, kiek robotas pasviręs, ir į kurią pusę pasviręs. Svarbiausia žinoti kur yra tas taškas, kada robotas stovi stabiliai. Principe lyg ir užtektų vien tik giroskopo, tačiau jis matuoja pasvirimo greitį, bet „nežino“ kur yra tas atskaitos taškas, aplink kurį reikia balansuoti. T.y. giroskopas duos vienodą rezultatą net jei robotas gulės ant šono. Kitaip sakant jis duoda tuo didesnė reikšmę, kuo pasvirimas staigesnis.

Kad sužinoti kada robotas stovi visiškai vertikaliai, reikia akselerometro. Akselerometras matuoja pagreitį, bet šiuo atveju, reikia pasvirimo kampo. Jei akselerometro matavimo ašis nukreipta žemyn, galima išmatuoti pasvirimo kampą. Akselerometras jaučia gravitaciją (svorio jėgą). Rezultatas bus vienareikšmiškas, t.y. bus aiškiai matoma, kiek robotas pasviręs nuo vertikalios padėties. Tačiau yra kita problema. Akselerometras tuo pačiu reaguoja ir į pagreitį, reiškia robotui važinėjant bus gaunama ne visai tiksli informacija. Kad rezultatas būtų tikslesnis, reikia informacijos iš dviejų daviklių – akselerometro ir giroskopo. Reikia tik sudėti abiejų daviklių reikšmes. Tam yra naudojamas komplementarinis filtras (complementary filter). Yra ir sudėtingesnis, bet tuo pačiu ir geresnis variantas – Kalmano filtras, bet jo veikimo principo aš nesuprantu. Bandžiau skaityt aprašymą, bet tai kaip kinų raštas. :)

Komplementarinio filtro pavyzdį nesunku rasti internete. Kad jis veiktų normaliai, reikia, kad daviklių reikšmių ribos būtų parinktos teisingai. Iš pradžių tai ne taip paprasta…

Pats balansavimo algoritmas gana paprastas. Iš daviklių gaunamos pasvirimo kampo ir svirimo greičio reikšmės. Jos patenka į filtrą, kurio reikšmė – pasvirimo kampas nuo taško, kuriame robotas nevirsta nė į vieną pusę. Ši reikšmė patenka į PID reguliatorių, kurio išėjimo reikšmė valdo poveikį varikliams – į kurią pusę ir kokiu greičiu jie turi pasisukti, kad kompensuoti pasvirimą. Jei reikėtų tik balansuoti, galima būtų abu variklius valdyti kartu. Tačiau aš norėjau, kad robotas galėtų ir posūkius daryti. Reiškia varikliai turi būti valdomi atskirai. Tačiau balansavimo metu jie veikia vienodai, nes balansuojama tik viena ašimi.

Aš gana nesunkiai padariau, kad robotas pradėtų balansuoti. T.y. kad poveikis veiktų teisinga kryptimi ir proporcingai pasvirimui. Bet to nepakanka. Reikia normaliai suderinti PID. Čia buvo sudėtingiau. Bėda tame, kad nežinomųjų buvo per daug. Aš nebuvau įsitikinęs, kad komplementarinis filtras veikia visai teisingai. Principe jis turėtų veikti taip, kad reaguotų į pasvirimą, bet nereaguotų į horizontalų pagreitį. Visiškai to pasiekti man nepavyko. Todėl derinant PID buvo klausimas – kas yra blogai, ar tai blogai veikiantis PID, ar blogai veikiantis filtras. Aš pasidariau grafikus (acc, giroskopo, filtro išėjimo), kad galėčiau akivaizdžiai matyti, kaip veikia filtras vartant ir judinant daviklius. Taip buvo galima derinti filtro veikimą ir matyti, gerėja situacija ar blogėja. Labiausia neaišku buvo su ACC Z ašimi. Buvo išvis neaišku kokia turi būti pradinė reikšmė, ir išvis kokią tai duoda naudą.

Pradžioje robotas balansavo labai blogai. Man pavyko pasiekti, kad jis kurį laiką išsilaikydavo ant ratų, bet neilgai. Pasirodo, kad kuo pagrindas, ant kurio jis stovi, minkštesnis, tuo stabiliau laikosi. Po ilgų derinimų pasiekiau, kad jis balansavo visai neblogai, t.y. galėdavo neribotą laiką išsilaikyti ant ratų, bet vos pastūmus – griūdavo.

Bandžiau patikrinti, ką duoda ACC Z ašis. Bandžiau visai atjungt (reikšmė visada vienoda). Viskas labai pablogėjo. Tada bandžiau parinkti pradines reikšmes. Visai netyčia atradau su kokia stabilumas akivaizdžiai pagerėjo. Bet ta reikšmė buvo visai ne tokia, kokia rekomenduojama daugumoje mano skaitytų aprašymų.

Pagaliau robotas tapo pakankamai stabilus. Tiesa pastumti buvo galima nedaug, akivaizdžiai trūko greičio varikliams, kad spėtų kompensuoti greitesnį pasvirimą. Reikėjo greitesnių variklių. Pabandžiau pakelti įtampą varikliams iki 6V. Teko išardyti BEC, nes jis negali duoti daugiau kaip 6V. Kaip minėjau, ant variklio draiverių krinta apie 1,5V. Reiškia reikėjo, kad duotų apie 7,5V. Ardosi šis BEC sunkokai, nes reikia nuimti ekraną. O perdaryti nesunku, tereikia pakeisti vieną rezistorių.

Padidinus įtampą, reikėjo perderinti PID, bet stabilumas pagerėjo. Kad būtų dar geriau, reiktų naudoti ratų enkoderius. Enkoderį galima irgi vadinti davikliu, kuris rodo, kiek pasisuko ratas. Aš iš pradžių abejojau ar be enkoderių išvis galima balansuoti. Pasirodo galima visai neblogai, bet be jų yra ir minusų. Dabar pastūmus robotą, jis, bandydamas išlaikyti pusiausvyrą, kažkiek pavažiuoja. Bet kiek pavažiuoja – neįmanoma žinoti. Balansuodamas irgi važinėja. Jei būtų galima žinoti kiek pavažiuoja, galima būtų tai irgi kompensuoti, ir tada robotas balansuotų vienoje vietoje. Be enkoderių neįmanoma balansuoti ant pasvirusio paviršiaus – robotas tiesiog rieda žemyn.

Kai pasiekiau normalų stabilumą, pabandžiau padaryti jam valdymą. Tam parašiau Android programą. Iš pradžių bandžiau padaryt valdymą spaudant mygtukus ekrane, bet tai buvo labai nepatogu, todėl perdariau, kad eitų valdyti tiesiog telefono pavertimu. Valdymas perduodamas per Bluetooth, tam robote yra įdėtas Bluetooth modulis.

Kaip paaiškėjo, valdymą padaryti sunkiau nei aš galvojau. Bėda tame, kad bet koks poveikis ratams, kurio reikia, kad robotas važiuotų pirmyn arba atgal, suktų į kurią nors pusę, labai destabilizuoja balansavimą. Be abejonės, balansavimo algoritmas veikia visą laiką. Posūkius padaryti lengviau. Vienas ratas gali suktis kuria nors kryptimi, kitas tuo metu balansuoja. To pakanka, galima suktis gana greitai, robotas išsilaiko nenugriuvęs. Bet važiavimas pirmyn ir atgal daug sudėtingesnis. Po ilgų vargų aš pasiekiau, kad valdyti galima neblogai. Bet idealiai nėra, važiuoti galima ribotu greičiu. Vos tik greičiau – robotas griūva. Čia labai svarbus variklių greitis. Ir reikia enkoderių, manau be jų geriau ir neįmanoma. Žinant ratų sukimosi greitį, galima būtų neleisti važiuoti greičiau, kad robotas nepasiektų ribos, kada jau nebegali balansuoti ir griūva.

Jei balansuojant svorio centras aukštai yra gerai, tai važiuojant kaip tik blogai. Aš pabandžiau šiek tiek pažeminti robotą, kad akumuliatorius būtų žemiau. Tai pagerino valdymą. Reiktų pabandyti dar žemiau, bet nėra kur dėti…

Ryšys per Bluetooth dvikryptis, todėl galiu matyti telefone bet kokią informaciją iš roboto. Derindamas buvau pasidaręs, kad rodė pasivirimo kampą, poveikius varikliams ir pan. Dabar palikau tik kad rodytų akumuliatoriaus įtampą.

6V šiems varikliams per daug. Gana greitai sudegė vieno iš jų šepetėliai. Dar viena problema – jų sukimosi greičiai nevienodi. Maža to, jie dar ir į priešingas puses sukasi skirtingu greičiu. Todėl naudoti juos galima tik kai nieko geresnio nėra. Reikia rimtesnių variklių.

Jau šiek tiek vėliau aš internete radau paprastą Kalmano filtro pavyzdį. Šis filtras labai supaprastintas, komentaruose ten minėjo, kad tai išvis kažkokia nesąmonė. Pabandžiau panaudot vietoje komplementarinio filtro. Keista, bet rezultatas man gavosi geresnis. Balansuoja pastebimai geriau ir valdymas pagerėjo.

Manau reikės kada nusipirkti geresnius variklius, pasidaryti enkoderius, ir pabandyti padaryti rimčiau… Beje, benaršydamas internete, buvau radęs vieno lietuvio video, kuriame jo darytas robotas važinėja daug geriau nei mano. :) Tobulėti yra kur…

2 dalis.

This entry was posted in Elektronika, Programavimas, Robotai. Bookmark the permalink.

2 Responses to Balansuojantis robotas

  1. Snake says:

    Jei tikrai posukius valdai kaip parasei tai negerai, reikia ne palikti ne viena rata balansavimui, o abu, tas paprasciausiai pasiekiama vienam motorui pridedant “greiti” is kito motoro itamant tiek pat “greicio”. Beja susitvarkes su varikliu “dead zone”?

  2. ReM says:

    Taip, aš suprantu, kad iš vieno reikėtų atimt, kitam pridėt. Bet padariau tokį šiek tiek supaprastintą variantą. Iš tikro nelieka jis visai ant vieno rato balansuot. Bet aš bandžiau – balansuoja ir ant vieno. O dėl “dead zone” tai nieko specialiai nedariau. Gaunasi kažkiek savaime kai PWM sumažėja iki tiek, kad jau nepasuka variklių. Irgi supaprastinta. :) Jei kada prisiruošiu dar prie jo prisėst, padarysiu geriau.

Leave a Reply

Your email address will not be published. Required fields are marked *