Sisukord:

Isetasakaalustav robot Magicbitist: 6 sammu
Isetasakaalustav robot Magicbitist: 6 sammu

Video: Isetasakaalustav robot Magicbitist: 6 sammu

Video: Isetasakaalustav robot Magicbitist: 6 sammu
Video: seeing wife face for first time #shorts 2024, Juuli
Anonim

See õpetus näitab, kuidas teha Magicbit dev tahvli abil isetasakaalustav robot. Selles projektis, mis põhineb ESP32 -l, kasutame arendusplaadina magicbitit. Seetõttu saab selles projektis kasutada mis tahes ESP32 arendusplaati.

Tarvikud:

  • magicbit
  • Kahe H-silla L298 mootorijuht
  • Lineaarne regulaator (7805)
  • Aku Lipo 7.4V 700mah
  • Inertsiaalne mõõtmisüksus (IMU) (6 kraadi vabadust)
  • käigumootorid 3V-6V DC

1. samm: lugu

Lugu
Lugu
Lugu
Lugu

Hei poisid, täna õpime selles õpetuses natuke keerukast asjast. See puudutab isetasakaalustavat robotit, kes kasutab Magicbitit koos Arduino IDE -ga. Nii et alustame.

Kõigepealt vaatame, mis on isetasakaalustav robot. Isetasakaalustav robot on kaherattaline robot. Eripäraks on see, et robot suudab end tasakaalustada ilma välist tuge kasutamata. Kui toide on sisse lülitatud, tõuseb robot püsti ja seejärel tasakaalustab pidevalt võnkumisliigutusi. Nii et nüüd on teil kõik ligikaudne ettekujutus isetasakaalustavast robotist.

2. samm: teooria ja metoodika

Teooria ja metoodika
Teooria ja metoodika

Roboti tasakaalustamiseks saame kõigepealt mõnelt andurilt andmed, et mõõta roboti nurka vertikaaltasapinna suhtes. Selleks kasutasime MPU6050. Pärast andurilt andmete saamist arvutame kalde vertikaaltasapinnale. Kui robot on sirges ja tasakaalustatud asendis, on kaldenurk null. Kui ei, siis on kaldenurk positiivne või negatiivne. Kui robot on esiküljele kallutatud, peaks robot liikuma esisuunas. Kui robot on tagurpidi kallutatud, peaks robot liikuma vastupidises suunas. Kui see kaldenurk on kõrge, peaks reageerimiskiirus olema kõrge. Vastupidi, kaldenurk on väike, siis peaks reaktsioonikiirus olema madal. Selle protsessi juhtimiseks kasutasime spetsiifilist teoreemi nimega PID. PID on juhtimissüsteem, mida kasutati paljude protsesside juhtimiseks. PID tähistab 3 protsessi.

  • P- proportsionaalne
  • I- lahutamatu
  • D- tuletis

Igal süsteemil on sisend ja väljund. Samamoodi on ka sellel juhtimissüsteemil teatud sisend. Selles juhtimissüsteemis on see kõrvalekalle stabiilsest olekust. Me nimetasime seda veaks. Meie roboti puhul on viga vertikaaltasapinna kaldenurk. Kui robot on tasakaalus, on kaldenurk null. Seega on vea väärtus null. Seetõttu on PID -süsteemi väljund null. See süsteem sisaldab kolme eraldi matemaatilist protsessi.

Esimene on korrutusviga numbrilisest võimendusest. Seda võimendust nimetatakse tavaliselt Kp -ks

P = viga*Kp

Teine on genereerida vea integraal aja domeenis ja korrutada see mõnest võimendusest. Seda kasu nimetati Ki -ks

I = integraal (viga)*Ki

Kolmas neist on tuletis ajavea veast ja korrutatakse see mõnevõrra kasumiga. Seda võimendust nimetatakse Kd -ks

D = (d (viga)/dt)*kd

Pärast ülaltoodud toimingute lisamist saame oma lõpliku väljundi

VÄLJUND = P+I+D

P -osa tõttu võib robot saada stabiilse positsiooni, mis on proportsionaalne kõrvalekaldega. I osa arvutab veapiirkonna ja aja graafiku. Nii püüab ta roboti alati täpselt stabiilsesse asendisse viia. D -osa mõõdab kallet ajas vs vea graafikut. Kui viga suureneb, on see väärtus positiivne. Kui viga väheneb, on see väärtus negatiivne. Seetõttu, kui robot viiakse stabiilsesse asendisse, väheneb reaktsioonikiirus ja see aitab vältida tarbetuid ületamisi. PID -teooria kohta saate lisateavet allolevalt lingilt.

www.arrow.com/en/research-and-events/articles/pid-controller-basics-and-tutorial-pid-implementation-in-arduino

PID-funktsiooni väljund on piiratud vahemikuga 0-255 (8-bitine PWM-eraldusvõime) ja see edastab mootoreid PWM-signaalina.

Samm: riistvara seadistamine

Riistvara seadistamine
Riistvara seadistamine

Nüüd on see riistvara seadistamise osa. Roboti disain sõltub sinust. Roboti keha projekteerimisel peate arvestama selle sümmeetrilisusega vertikaaltelje suhtes, mis asub mootoriteljel. Aku asub allpool. Seetõttu on robotit lihtne tasakaalustada. Oma konstruktsioonis kinnitame Magicbiti plaadi keha külge vertikaalselt. Kasutasime kahte 12V käigukastiga mootorit. Kuid võite kasutada mis tahes käigukastiga mootoreid. see sõltub teie roboti mõõtmetest.

Kui me räägime vooluringist, töötab see 7,4 V Lipo akuga. Magicbit kasutas toiteallikaks 5 V. Seetõttu kasutasime aku pinge reguleerimiseks 5 V regulaatorit 7805. Magicbiti hilisemates versioonides pole seda regulaatorit vaja. Kuna see toidab kuni 12V. Mootorijuhile tarnime otse 7.4V.

Ühendage kõik komponendid vastavalt allolevale skeemile.

Samm 4: Tarkvara seadistamine

Koodis kasutasime PID -väljundi arvutamiseks PID -teeki.

Selle allalaadimiseks minge järgmisele lingile.

www.arduinolibraries.info/libraries/pid

Laadige alla selle uusim versioon.

Andurite paremate näitude saamiseks kasutasime DMP raamatukogu. DMP tähistab digitaalset liikumisprotsessi. See on MPU6050 sisseehitatud funktsioon. Sellel kiibil on integreeritud liikumisprotsessi üksus. Seega tuleb lugeda ja analüüsida. Pärast seda genereerib mikrokontrollerile (antud juhul Magicbit (ESP32)) müravabasid täpseid väljundeid. Kuid mikrokontrolleri poolel on palju töid selle näidu võtmiseks ja nurga arvutamiseks. Nii et lihtsalt kasutasime MPU6050 DMP raamatukogu. Laadige see alla järgmise lingi kaudu.

github.com/ElectronicCats/mpu6050

Raamatukogude installimiseks avage Arduino menüüst tööriistad-> kaasake raamatukogu-> add.zip raamatukogu ja valige allalaaditud raamatukogufail.

Koodis peate seadistuspunkti nurka õigesti muutma. PID -i konstantsed väärtused on robotiti erinevad. Seadistades seadistage esmalt Ki ja Kd väärtused nulliks ja suurendage seejärel Kp, kuni reaktsioonikiirus on parem. Rohkem Kp põhjustab rohkem ületamisi. Seejärel suurendage Kd väärtust. Suurendage seda alati väga väikestes kogustes. See väärtus on üldiselt madal kui teised väärtused. Nüüd suurendage Ki, kuni teil on väga hea stabiilsus.

Valige õige COM -port ja plaadi tüüp. laadige kood üles. Nüüd saate mängida oma isetehtud robotiga.

Samm: skeemid

Skeemid
Skeemid

6. samm: kood

#kaasake

#include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; bool dmpReady = vale; // seada tõeseks, kui DMP init õnnestus uint8_t mpuIntStatus; // omab tegelikku katkestuse oleku baiti MPU -st uint8_t devStatus; // tagastab oleku pärast iga seadme toimingut (0 = õnnestumine,! 0 = viga) uint16_t packetSize; // eeldatav DMP paketi suurus (vaikimisi on 42 baiti) uint16_t fifoCount; // kõigi baitide arv praegu FIFO -s uint8_t fifoBuffer [64]; // FIFO salvestuspuhver Quaternion q; // [w, x, y, z] kvaternionikonteiner VectorFloat gravity; // [x, y, z] gravitatsioonivektori ujuk ypr [3]; // [kaldumine, kaldenurk, rull] kaldumine/kaldenurk/rullmahuti ja gravitatsioonivektor double originalSetpoint = 172,5; kahekordne seadeväärtus = originalSetpoint; kahekordne liigutamineAngleOffset = 0,1; kahekordne sisend, väljund; int moveState = 0; topelt Kp = 23; // seada P esimene kahekordne Kd = 0,8; // see väärtus üldiselt väike kahekordne Ki = 300; // see väärtus peaks olema kõrge parema stabiilsuse tagamiseks PID pid (& sisend, & väljund, & seadeväärtus, Kp, Ki, Kd, DIRECT); // pid initsialiseeri int motL1 = 26; // 4 tihvti mootori ajamile int motL2 = 2; int motR1 = 27; int motR2 = 4; lenduv bool mpuInterrupt = false; // näitab, kas MPU katkestusnõel on läinud tühjaks dmpDataReady () {mpuInterrupt = true; } void setup () {ledcSetup (0, 20000, 8); // pwm setup ledcSetup (1, 20000, 8); ledcSetup (2, 20000, 8); ledcSetup (3, 20000, 8); ledcAttachPin (motL1, 0); // mootorite pinmode ledcAttachPin (motL2, 1); ledcAttachPin (motR1, 2); ledcAttachPin (motR2, 3); // liitu I2C siiniga (I2Cdev raamatukogu ei tee seda automaatselt) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin (); Wire.setClock (400000); // 400 kHz I2C kell. Kommenteerige seda rida, kui teil on koostamisraskusi #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire:: setup (400, true); #endif Serial.println (F ("I2C seadmete lähtestamine …")); pinMode (14, INPUT); // jadaühenduse initsialiseerimine // (115200 on valitud, kuna see on vajalik teekannu demoväljundiks, kuid see on // tõesti teie otsustada sõltuvalt teie projektist) Serial.begin (9600); while (! Seeria); // oodake Leonardo loendamist, teised jätkavad kohe // seadme lähtestamine Serial.println (F ("I2C seadmete lähtestamine …")); mpu.initialize (); // kontrolli ühendust Serial.println (F ("Seadmeühenduste testimine …")); Serial.println (mpu.testConnection ()? F ("MPU6050 ühendus õnnestus"): F ("MPU6050 ühendus nurjus")); // laadige ja konfigureerige DMP Serial.println (F ("DMP vormindamine …")); devStatus = mpu.dmpInitialize (); // sisestage siin oma güroskoopide nihked, skaleeritud minimaalse tundlikkuse järgi mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // minu testkiibi tehase vaikeseade 1688 // veenduge, et see toimiks (tagastab 0, kui jah), kui (devStatus == 0) {// lülitage DMP sisse nüüd, kui see on valmis Serial.println (F ("DMP lubamine… ")); mpu.setDMPEnabled (tõene); // lubage Arduino katkestuste tuvastamine Serial.println (F ("Katkestuste tuvastamise lubamine (Arduino väline katkestus 0)…")); attachInterrupt (14, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); // seadistage meie DMP Ready lipp, nii et põhisilmuse () funktsioon teab, et seda on okei kasutada Serial.println (F ("DMP valmis! Ootan esimest katkestust …")); dmpReady = tõsi; // saada oodatud DMP paketi suurus hilisemaks võrdluseks packetSize = mpu.dmpGetFIFOPacketSize (); // PID seadistamine pid. SetMode (AUTOMATIC); pid. SetSampleTime (10); pid. SetOutputLimits (-255, 255); } muu {// VIGA! // 1 = esialgne mälu laadimine ebaõnnestus // 2 = DMP konfiguratsiooni värskendamine ebaõnnestus // (kui see läheb katki, on tavaliselt kood 1) Serial.print (F ("DMP -i initsialiseerimine ebaõnnestus (kood"))); Seeria. print (devStatus); Serial.println (F (")")); }} void loop () {// kui programmeerimine ebaõnnestus, ärge proovige midagi teha, kui (! dmpReady) naaseb; // oodake, kuni MPU katkestus või lisapakett (id) on saadaval (! mpuInterrupt && fifoCount <packetSize) {pid. Compute (); // seda ajavahemikku kasutatakse andmete laadimiseks, nii et saate seda kasutada muude arvutuste jaoks motorSpeed (väljund); } // lähtestage katkestuse lipp ja hankige INT_STATUS bait mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); // saada praegune FIFO loend fifoCount = mpu.getFIFOCount (); // kontrollige ülevoolu (seda ei tohiks kunagi juhtuda, kui meie kood pole liiga ebaefektiivne) if ((mpuIntStatus & 0x10) || fifoCount == 1024) {// lähtestatakse, et saaksime puhtalt jätkata mpu.resetFIFO (); Serial.println (F ("FIFO ülevool!")); // muidu kontrollige DMP -andmete katkestamise katkemist (seda peaks sageli juhtuma)} else if (mpuIntStatus & 0x02) {// oodake õiget saadaolevat andmepikkust, peaks olema VÄGA lühike ooteaeg (fifoCount 1 pakett saadaval // (see loeme kohe rohkem, ilma katkestust ootamata. print ("ypr / t"); Serial.print (ypr [0] * 180/M_PI); // euler nurgad Serial.print ("\ t"); Serial.print (ypr [1] * 180/M_PI); Serial.print ("\ t"); Serial.println (ypr [2] * 180/M_PI); #endif input = ypr [1] * 180/M_PI + 180;}} void motorSpeed (int PWM) {float L1, L2, R1, R2; kui (PWM> = 0) {// edasi suund L2 = 0; L1 = abs (PWM); R2 = 0; R1 = abs (PWM); kui (L1> = 255) { L1 = R1 = 255;}} muu {// tagasisuund L1 = 0; L2 = abs (PWM); R1 = 0; R2 = abs (PWM); kui (L2> = 255) {L2 = R2 = 255; }} // mootori ajam ledcWrite (0, L1); ledcWrite (1, L2); ledcWrite (2, R1*0,97); // 0,97 on kiiruse fakt või kuna paremal mootoril on suurem kiirus kui vasakul, vähendame seda seni, kuni mootori pöörlemiskiirused on võrdsed ledcWrite (3, R2*0,97);

}

Soovitan: