Мазмуну:

Magicbitтен өзүн -өзү тең салуучу робот: 6 кадам
Magicbitтен өзүн -өзү тең салуучу робот: 6 кадам

Video: Magicbitтен өзүн -өзү тең салуучу робот: 6 кадам

Video: Magicbitтен өзүн -өзү тең салуучу робот: 6 кадам
Video: Трактористы (комедия, реж. Иван Пырьев, 1939 г.) 2024, Июль
Anonim

Бул окуу куралы Magicbit dev тактасын колдонуу менен өзүн -өзү тең салмактай турган роботту кантип жасоону көрсөтөт. Биз ESP32ге негизделген бул долбоордун өнүгүү тактасы катары magicbitти колдонуп жатабыз. Ошондуктан бул долбоордо каалаган ESP32 өнүктүрүү тактасы колдонулушу мүмкүн.

Берилиштер:

  • magicbit
  • Кош H-bridge L298 мотор айдоочусу
  • Сызыктуу регулятор (7805)
  • Lipo 7.4V 700mah батарея
  • Инерциалдык өлчөө бирдиги (IMU) (6 градус эркиндик)
  • 3V-6V DC редукторлору

1 -кадам: Окуя

Окуя
Окуя
Окуя
Окуя

Эй балдар, бүгүн бул үйрөткүчтө биз бир аз татаал нерсени үйрөнөбүз. Бул Arduino IDE менен Magicbitти колдонуп, өзүн -өзү теңдештирүүчү робот жөнүндө. Андыктан баштайлы.

Биринчиден, өзүбүздү тең салмактай турган роботту карап көрөлү. Өзүн тең салмактоочу робот - эки дөңгөлөктүү робот. Өзгөчөлүгү - робот эч кандай тышкы колдоону колдонбостон өзүн тең салмактай алат. Күч күйгүзүлгөндө робот ордунан туруп, термелүү кыймылдарын колдонуу менен тең салмактуу болот. Ошентип, азыр сизде тең салмактуу робот жөнүндө бир аз ойлор бар.

2 -кадам: Теория жана методология

Теория жана методология
Теория жана методология

Роботту тең салмакташтыруу үчүн, адегенде роботтун вертикалдык тегиздикке болгон бурчун өлчөө үчүн кээ бир сенсорлордон маалымат алабыз. Бул үчүн биз MPU6050 колдондук. Сенсордон маалыматтарды алгандан кийин вертикалдуу тегиздикке эңкейүүнү эсептейбиз. Эгерде робот түз жана тең салмактуу абалда болсо, анда кыйшайуу бурчу нөлгө барабар. Болбосо, анда жантаюу бурчу оң же терс мааниге ээ. Эгерде робот алдыңкы капталга кыйшайса, анда робот алдыга карай жылышы керек. Ошондой эле, эгер робот артка кыйшайса, анда робот артка карай жылышы керек. Бул ийилүү бурчу жогору болсо, анда жооп ылдамдыгы жогору болушу керек. Тескерисинче, жантаюу бурчу төмөн, андан кийин реакциянын ылдамдыгы төмөн болушу керек. Бул процессти көзөмөлдөө үчүн биз PID деп аталган белгилүү бир теореманы колдондук. PID көптөгөн процесстерди көзөмөлдөө үчүн колдонулган башкаруу системасы. PID 3 процессти билдирет.

  • P- пропорционалдуу
  • I- интегралдык
  • D- туунду

Ар бир системада киргизүү жана чыгаруу бар. Ошол сыяктуу эле, бул башкаруу системасы да кандайдыр бир салымга ээ. Бул башкаруу системасында бул туруктуу абалдан четтөө. Биз муну ката деп атаганбыз. Биздин роботто ката вертикалдуу тегиздиктен эңкейиш бурчу. Эгерде робот тең салмактуу болсо, анда жантаюу бурчу нөлгө барабар. Ошентип, ката мааниси нөлгө барабар болот. Ошентип, PID системасынын өндүрүшү нөлгө барабар. Бул система үч башка математикалык процессти камтыйт.

Биринчиси, сандык кирешенин көбөйтүү катасы. Бул киреше көбүнчө Kp деп аталат

P = ката*Kp

Экинчиси, убакыт домениндеги катанын интегралын жаратуу жана аны кандайдыр бир кирешеден көбөйтүү. Бул пайда Ки деп аталат

I = Интегралдык (ката)*Ки

Үчүнчүсү, убакыт домениндеги катанын туундусу жана аны кандайдыр бир кирешеге көбөйтүү. Бул пайда Kd деп аталат

D = (d (ката)/dt)*kd

Жогорудагы операцияларды кошкондон кийин биз акыркы жыйынтыкты алабыз

ЧЫГУУ = P+I+D

Р бөлүгүнүн айынан робот четтөөгө пропорционалдуу туруктуу абалды ала алат. Мен бир бөлүгү ката жана убакыт графигин эсептейт. Ошентип, ал роботту дайыма туруктуу абалга жеткирүүгө аракет кылат. D бөлүгү убакыттын өтүшү менен катанын графигин өлчөйт. Эгерде ката көбөйүп жатса, бул оң болот. Эгерде ката төмөндөп жатса, бул көрсөткүч терс. Ушундан улам, робот туруктуу абалга өткөндө, реакциянын ылдамдыгы төмөндөйт жана бул ашыкча ашыкчаларды кетирүүгө жардам берет. Сиз төмөндө көрсөтүлгөн бул шилтемеден PID теориясы жөнүндө көбүрөөк биле аласыз.

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

PID функциясынын чыгышы 0-255 диапазонунда (8 бит PWM токтому) жана моторлорго PWM сигналы катары берилет.

3 -кадам: Аппараттык орнотуу

Аппараттык орнотуу
Аппараттык орнотуу

Эми бул аппараттык орнотуунун бир бөлүгү. Роботтун дизайны сизге көз каранды. Роботтун денесин долбоорлоодо, мотор огунда жайгашкан вертикалдуу огуна симметриялуу караш керек. Батарея пакети төмөндө жайгашкан. Ошентип, роботту тең салмакташтыруу оңой. Биздин дизайнда Magicbit тактасын денеге тигинен тигебиз. Биз 12V эки тиштүү моторду колдондук. Бирок ар кандай тиштүү моторлорду колдонсоңуз болот. Бул сиздин роботтун өлчөмүнө жараша болот.

Биз схема жөнүндө сүйлөшкөндө, ал 7.4V Lipo батарейкасы менен иштейт. Magicbit кубаттоо үчүн 5В колдонгон. Ошентип, биз 5V үчүн батарея чыңалуусун жөнгө салуу үчүн 7805 жөндөгүчтү колдондук. Magicbitтин кийинки версияларында бул жөнгө салуучунун кереги жок. Анткени ал 12 В чейин иштейт. Биз түздөн -түз мотор айдоочусу үчүн 7.4V менен камсыздайбыз.

Бардык компоненттерди төмөнкү схемага ылайык туташтырыңыз.

4 -кадам: Программаны орнотуу

Коддо PID чыгарылышын эсептөө үчүн PID китепканасын колдондук.

Аны жүктөө үчүн төмөнкү шилтемеге өтүңүз.

www.arduinolibraries.info/libraries/pid

Анын акыркы версиясын жүктөп алыңыз.

Сенсордун жакшыраак окулушу үчүн биз DMP китепканасын колдондук. DMP санарип кыймыл процессин билдирет. Бул MPU6050 камтылган өзгөчөлүгү. Бул чипте кыймыл процессинин бирдиги бар. Андыктан окуу жана анализ керек. Микроконтроллерге үнсүз так чыгууларды жараткандан кийин (бул учурда Magicbit (ESP32)). Бирок микроконтроллер тарапта бул көрсөткүчтөрдү алуу жана бурчту эсептөө үчүн көптөгөн иштер бар. Ошентип, биз MPU6050 DMP китепканасын колдондук. Аны goint аркылуу төмөнкү шилтемеге жүктөп алыңыз.

github.com/ElectronicCats/mpu6050

Китепканаларды орнотуу үчүн, Arduino менюсунда Tools-> Library-> add.zip китепканасына кирип, жүктөп алган китепкана файлын тандаңыз.

Коддо белгиленген чекиттин бурчун туура өзгөртүү керек. PID туруктуу баалуулуктары роботтон роботко айырмаланат. Ошентип, муну тууралоодо, адегенде Ki жана Kd маанилерин нөлгө коюп, андан кийин реакциянын ылдамдыгын жакшыртмайынча Kp жогорулатыңыз. Дагы Kp ашыкча чектен чыгууга себеп болот. Андан кийин Kd маанисин жогорулатыңыз. Аны дайыма аз өлчөмдө көбөйтүңүз. Бул баа башка баалуулуктарга караганда жалпысынан төмөн. Эми сиз абдан жакшы туруктуулукка ээ болгонго чейин Киди көбөйтүңүз.

Туура COM портун тандап, тактаны териңиз. кодду жүктөө. Эми сиз DIY роботуңуз менен ойной аласыз.

5 -кадам: Схемалар

Схемалар
Схемалар

6 -кадам: Код

#кошуу

#include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; bool dmpReady = false; // эгер DMP init ийгиликтүү uint8_t mpuIntStatus болгон болсо, анда чындыкты коюңуз; // MPU uint8_t devStatusтан чыныгы үзгүлтүк статусунун байтына ээ; // ар бир түзмөк операциясынан кийин статусун кайтаруу (0 = ийгилик,! 0 = ката) uint16_t packetSize; // күтүлгөн DMP пакетинин өлчөмү (демейки 42 байт) uint16_t fifoCount; // учурда FIFO uint8_t fifoBufferдеги бардык байттардын саны [64]; // FIFO сактоо буфери Quaternion q; // [w, x, y, z] төрттүк контейнери VectorFloat гравитациясы; // [x, y, z] гравитациялык вектор float ypr [3]; // [yaw, pitch, roll] yaw/pitch/roll контейнер жана тартылуу вектору кош originalSetpoint = 172.5; кош чекит = originalSetpoint; double moveAngleOffset = 0.1; кош киргизүү, чыгаруу; int moveState = 0; double Kp = 23; // set P first double Kd = 0.8; // бул маани жалпысынан кичинекей кош Ki = 300; // бул көрсөткүч жакшыраак туруктуулук үчүн болушу керек PID pid (& input, & output, & setpoint, Kp, Ki, Kd, DIRECT); // pid initialize int motL1 = 26; int motR1 = 27; int motR2 = 4; туруксуз бол mpuInterrupt = false; // MPU үзгүлтүк пини жогорку боштукка кеткенин көрсөтөт 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); // мотордун pinmode ledcAttachPin (motL2, 1); ledcAttachPin (motR1, 2); ledcAttachPin (motR2, 3); // I2C автобусуна кошулуу (I2Cdev китепканасы муну автоматтык түрдө жасабайт) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin (); Wire.setClock (400000); // 400 кГц I2C сааты. Компиляцияда кыйынчылыктар болсо, бул сапка комментарий жазыңыз #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire:: setup (400, true); #endif Serial.println (F ("I2C түзмөктөрүн инициализациялоо …")); pinMode (14, INPUT); // сериялык байланышты инициализациялоо // (115200 тандалган, анткени ал Чайнек Демо чыгаруу үчүн талап кылынат, бирок бул чындыгында сиздин долбоорго жараша) Serial.begin (9600); while (! Сериялык); // Леонардонун саналышын күт, башкалар дароо улантышат // Serial.println түзмөгүн инициализациялоо (F ("I2C түзмөктөрүн инициализациялоо …")); mpu.initialize (); // байланышты текшерүү Serial.println (F ("Түзмөктүн туташууларын текшерүү …")); Serial.println (mpu.testConnection ()? F ("MPU6050 туташуусу ийгиликтүү"): F ("MPU6050 туташуусу ишке ашпай калды")); // DMP Serial.println жүктөө жана конфигурациялоо (F ("DMP башталууда …")); devStatus = mpu.dmpInitialize (); // бул жерде минус сезгичтиги үчүн масштабдалган өз гиро ордун камсыздоо mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // Менин сыноо чипим үчүн 1688 фабрикалык демейки // анын иштешин текшериңиз (эгер болсо 0 кайтарылат), эгер (devStatus == 0) {// DMPти күйгүзүңүз, азыр ал даяр Serial.println (F ("DMP иштетүү… ")); mpu.setDMPEnabled (чыныгы); // Arduino үзгүлтүгүн аныктоону иштетүү Serial.println (F ("Үзгүлтүктү аныктоону иштетүү (Arduino тышкы үзгүлтүк 0) …")); attachInterrupt (14, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); // DMP Ready желегибизди койгула, ошондо негизги loop () функциясы аны колдонуунун туура экенин билет Serial.println (F ("DMP даяр! Биринчи үзгүлтүктү күтүүдө…")); dmpReady = чын; // кийинчерээк салыштыруу үчүн күтүлгөн DMP пакетинин өлчөмүн алуу packetSize = mpu.dmpGetFIFOPacketSize (); // орнотуу PID pid. SetMode (АВТОМАТТЫК); pid. SetSampleTime (10); pid. SetOutputLimits (-255, 255); } башка {// КАТА! // 1 = эс тутумдун баштапкы жүктөлүшү ишке ашпай калды // 2 = DMP конфигурациясынын жаңыртуулары ишке ашпай калды // (эгер ал бузула турган болсо, адатта код 1 болот) Serial.print (F ("DMP башталбай калды (код")); Сериялык. басып чыгаруу (devStatus); Serial.println (F (")")); }} void loop () {// эгерде программалоо ишке ашпай калса, (! dmpReady) кайтса эч нерсе кылууга аракет кылбаңыз; // MPU үзгүлтүккө учуроосун же кошумча пакеттерди (! чыгаруу); } // үзгүлтүк желегин баштапкы абалга келтирүү жана INT_STATUS байтты алуу mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); // учурдагы FIFO санын алыңыз fifoCount = mpu.getFIFOCount (); // толуп кетүүнү текшериңиз (бул биздин код өтө эффективдүү болбосо эч качан болбошу керек) if ((mpuIntStatus & 0x10) || fifoCount == 1024) {// баштапкы абалга келтирүү үчүн, биз таза уланта алабыз mpu.resetFIFO (); Serial.println (F ("FIFO толушу!")); // Болбосо, DMP дайындарынын үзгүлтүккө учуроосун текшериңиз (бул тез -тез болуп турушу керек)} эгерде (mpuIntStatus & 0x02) {// туура болгон маалыматтын узундугун күтсөңүз, абдан кыска күтүү керек (fifoCount 1 пакети жеткиликтүү // (бул бизге үзгүлтүккө учуроону күтпөстөн дароо көбүрөөк окууга мүмкүнчүлүк берет) fifoCount -= packetSize; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravity, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & grif) басып чыгаруу ("ypr / t"); Serial.print (ypr [0] * 180/M_PI); // euler бурчтары 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; if (PWM> = 0) {// алдыга карай багыт L2 = 0; L1 = abs (PWM); R2 = 0; R1 = abs (PWM); if (L1> = 255) { L1 = R1 = 255;}} башка {// артка багыт L1 = 0; L2 = abs (PWM); R1 = 0; R2 = abs (PWM); if (L2> = 255) {L2 = R2 = 255; }} // мотор диск ledcWrite (0, L1); ledcWrite (1, L2); ledcWrite (2, R1*0.97); // 0.97 - бул ылдамдык фактысы же, анткени оң мотор сол моторго караганда жогорку ылдамдыкка ээ, ошондуктан мотор ылдамдыгы ledcWrite (3, R2*0.97) бирдей болгонго чейин аны азайтабыз;

}

Сунушталууда: