LQR kontroleris

Konstruodamas balansuojančius robotus iki šiol naudojau PID kontrolerius. Paskutiniame buvo dvigubas PID, vienas kontroliuoja poveikį ratams, kitas roboto pasvirimą, priklausomai nuo greičio ir valdymo signalų. Pasivirimo kontrolė reikalinga tam, kad galima būtų geriau priešintis išoriniams poveikiams (pastūmimas), arba kai reikia greitai stabdyti (pasvyra atgal, kad neapsiverstų).

PID yra gana paprastas ir visai neblogas kontroleris. Tačiau yra ir kitas – LQR. LQR raidės reiškia “linear-quadratic regulator”. Kartais jis vadinamas LQR filtru. Aš jau seniai bandžiau apie jį paskaitinėt, bet bėda tame, kad pasižiūrėjus į formules, kaip ten viskas skaičiuojama, dingdavo noras ką nors daryt. Aprašymų galima rasti kiek tik nori, tos formulės irgi būtų ne tokios jau baisios, galima pasinaudoti MATLAB, bet yra kita problema. Kad apskaičiuoti LQR koeficientus, reikia turėti sistemos modelį. Pvz. žinoti, arba kažkaip apskaičiuoti rato kampinį greitį, variklio sukimo momentą (nežinau net ar teisingai lietuviškai išverčiau) ir pan. Neturėjau noro gilintis kaip tai galima būtų apskaičiuot.

Galima dar susirasti kokių nors projektų internete, kur naudojamas LQR. Nepasakyčiau, kad tai daug padėjo, bet paaiškėjo, kad pats LQR šiaip jau labai paprastas. Iš pirmo žvilgsnio jis netgi paprastesnis už PID. Visa esmė koeficientai. Kiek teko skaityt, jų parinkti tiesiog derinant kaip PID atveju, nepavyksta. Bet visur rašo, kad LQR žymiai geriau už PID. O jei geriau, būtų neblogai pabandyt ir suprast kuo gi jis geresnis.

LQR atrodo taip: sakykim, kad Q, tai reikalingas poveikis ratams, kad sistema išliktų stabili. Taigi, Q = angle*K1+rate*K2+speed*K3+pos*K4. Turim keturis parametrus (daviklių reikšmes), kurios paprasčiausiai sudedamos. Visa esmė čia tame, kad tie parametrai būtų teisingose ribose. Ir ne tik teisingose ribose, bet ir išvis būtų tai, kas turi būti… Pradžioje nelabai aišku…

Angle – pasvirimo kampas. Čia viskas aišku, giroskopas, akselerometrai, kalman arba complementary filtras.

Rate – pasvirimo greitis. Kas matuoja pasvirimo greitį? Giroskopas. Tai yra grynai giroskopo reikšmė, bet jokių akselerometrų ir filtrų.

Speed – judėjimo greitis. Kokiu greičiu sukasi ratai. Mano atveju tai gaunama iš encoderių.

Pos – kiek pasisuko ratai, t. y. skaičiuojama kiek robotas pavažiavo. Rezultatas iš encoderių, kad balansuodamas palaipsniui nenuvažiuotų kažin kur ir kad pastūmus sugrįžtų atgal.

Pirmą kartą (prieš kokius du metus) aš bandžiau pakeisti PID į LQR šiame robote. Koeficientus bandžiau parinkt. Gavosi… tiksliau beveik nesigavo. Negalima sakyt, kad visai neveikė, bet veikė blogai. Robotas ant ratų išsilaikydavo ne daugiau kaip 10-15 sekundžių. Geriau niekaip nepavyko suderint. Tai lyg ir patvirtino, kad suderinti paprasčiausiai parenkant koeficientus, neįmanoma. Taip ir numečiau…

Po kiek laiko pamačiau, kad eBay pasirodė nebrangių variklių su encoderiais. Nusipirkau porą, bet eilinį kartą įsitikinau, kad pigiai ir gerai nebūna. Reduktoriai kliba. O encoderiai visai neblogi, tiesa tikslumas nedidelis (holo davikliai). Padaryta gana protingai, jie uždėti tiesiogiai ant variklio, reiškia tikslumas padidėja nes reduktorius ten, jei gerai pamenu, 1:30, reiškia encoderio impulsų skaičius padidėja 30 kartų per vieną rato apsisukimą. Specialiai paėmiau 500 RPM variklius, nes norėjau padaryti labai greitą robotą.

Visos korpuso detalės atspausdintos.

Elektronika labai paprasta, atmega328 (arduino), variklių draiveris TB6612, step-up konverteris MT3608, MPU6050, NRF24L01. Step-up konverteris reikalingas tam, kad naudoju mažą 1000MAh dviejų celių akumuliatorių, o varikliams reikia 12V.

Buvo keistas atvejis su variklių draiveriu. Rašoma, kad jis gali veikti iki 15V tačiau pajungus prie 12V, draiverio plokštėje esantis SMD kondensatorius tiesiog sprogo. Keista tai, kad pakeitus jį, viskas veikia. Dar keisčiau tai, kad pabandžius kitą draiverį, rezultatas lygiai toks pat – kondensatorius irgi sprogo. Nežinau, ar ten kinai įdėjo mažesnės įtampos (nėra užrašyta koks jis ten yra), ar step-up konverteris pasileisdamas paduoda didesnę įtampą. Bet tai mažai tikėtina, nes šiaip jis veikia puikiai ir daugiau jokių problemų nepastebėjau.

Ratai maži (irgi atspausdinti). Kuo mažesni ratai, tuo mažiau jaučiasi reduktorių klibėjimas.

Koeficientus parinkinėjau ilgai. Pasidariau, kad galėčiau keisti distanciniu būdu per bluetooth. Tokiu būdu suderinti pavyko. Pasirodo, nėra tai jau taip neįmanoma, po kiek laiko pradedi jausti kas nuo ko priklauso, ir kaip pakeitimai paveikia elgesį. Bandžiau ir su didesniais ratais, bet rezultatas blogesnis, nes variklių RPM didelis. Robotas važinėja ir taip pakankamai greitai.

Kas gavosi galima matyti video.

Kaip matosi, veikia puikiai. Nėra idealu, reduktorių klibėjimas jaučiasi, gal pasistengus galima gaut geresnį rezultatą, bet tai labai neblogai. Ar geriau už PID? Nežinau, bet greičiausiai ne. Manau su PID galima padaryti taip pat. T.y. kažkokių LQR privalumų bent jau šiuo atveju aš nematau. Gal netgi pabandysiu pakeisti programą, kad veiktų su dvigubu PID. Palyginsiu.

Robotas valdomas iš telefono, arba per NRF24l01. Pajungiant pritrūko vieno išvado pas atmega328, todėl ryšys per NRF24l01 gavosi tik į roboto pusę. Atgalinio ryšio nėra.

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

One Response to LQR kontroleris

  1. Lakshmanan says:

    Very good robot. I am trying to build one. Please can you share the code?

Leave a Reply

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