Мазмұны:

Magicbit -тен өзін -өзі теңестіретін робот: 6 қадам
Magicbit -тен өзін -өзі теңестіретін робот: 6 қадам

Бейне: Magicbit -тен өзін -өзі теңестіретін робот: 6 қадам

Бейне: Magicbit -тен өзін -өзі теңестіретін робот: 6 қадам
Бейне: Learn Coding with MagicBit 2024, Шілде
Anonim

Бұл оқулықта Magicbit dev тақтасының көмегімен өзін -өзі теңестіретін роботты қалай жасау керектігін көрсетеді. Біз ESP32 -ге негізделген осы жобаның даму тақтасы ретінде magicbit қолданамыз. Бұл жобада кез келген ESP32 даму тақтасын қолдануға болады.

Жабдықтар:

  • сиқырлы бит
  • Қос H-көпір L298 мотор жүргізушісі
  • Сызықтық реттегіш (7805)
  • Lipo 7.4V 700mah батарея
  • Инерциялық өлшеу бірлігі (IMU) (еркіндік 6 градус)
  • 3В-6В тұрақты беріліс қозғалтқыштары

1 -қадам: Әңгіме

Оқиға
Оқиға
Оқиға
Оқиға

Балалар, бүгін біз бұл оқулықта кішкене күрделі нәрселер туралы білетін боламыз. Бұл Magicbit көмегімен Arduino IDE көмегімен өзін -өзі теңестіретін робот туралы. Ендеше бастайық.

Алдымен, өзін -өзі теңестіретін робот деген не екенін қарастырайық. Өзін -өзі теңестіретін робот - екі доңғалақты робот. Ерекшелігі - робот сыртқы қолдауды пайдаланбай өзін теңгере алады. Қуат қосылған кезде робот орнынан тұрады, содан кейін ол тербеліс қозғалысын қолдана отырып үздіксіз теңдестіріледі. Енді сізде барлығын теңестіретін робот туралы түсінік бар.

2 -қадам: Теория мен әдістеме

Теория мен әдістеме
Теория мен әдістеме

Роботты теңестіру үшін алдымен роботтың тік жазықтыққа бұрышын өлшеу үшін сенсордан мәліметтер аламыз. Ол үшін біз MPU6050 қолдандық. Сенсордан деректерді алғаннан кейін біз вертикаль жазықтыққа қисайуды есептейміз. Егер робот түзу және теңдестірілген күйде болса, онда көлбеу бұрышы нөлге тең. Олай болмаса, көлбеу бұрышы оң немесе теріс мән болады. Егер робот алдыңғы жағына қисайса, онда робот алдыңғы бағытта қозғалуы керек. Егер робот артқа қарай қисайса, робот кері бағытта қозғалуы керек. Егер бұл көлбеу бұрышы жоғары болса, онда жауап беру жылдамдығы жоғары болуы керек. Керісінше көлбеу бұрышы төмен, содан кейін реакция жылдамдығы төмен болуы керек. Бұл процесті басқару үшін біз PID деп аталатын арнайы теореманы қолдандық. PID - бұл көптеген процестерді басқаратын басқару жүйесі. PID 3 процесті білдіреді.

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

Әр жүйеде кіріс және шығыс бар. Дәл осылай бұл басқару жүйесінде де біраз кіріс бар. Бұл басқару жүйесінде бұл тұрақты күйден ауытқу. Біз мұны қателік деп атадық. Біздің роботта қателік - тік жазықтықтан көлбеу бұрышы. Егер робот тепе -тең болса, көлбеу бұрышы нөлге тең болады. Сондықтан қате мәні нөлге тең болады. Сондықтан PID жүйесінің шығысы нөлге тең. Бұл жүйе үш бөлек математикалық процесті қамтиды.

Біріншісі - сандық кірістің көбейту қателігі. Бұл табыс әдетте Kp деп аталады

P = қате*Kp

Екіншісі - уақыт аймағындағы қатенің интегралын құру және оны кейбір пайдадан көбейту. Бұл табыс Ки деп аталады

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

Үшіншісі - уақыт аймағындағы қатенің туындысы және оны белгілі бір пайда мөлшеріне көбейту. Бұл табыс Kd деп аталады

D = (d (қате)/dt)*kd

Жоғарыда көрсетілген операцияларды қосқаннан кейін біз соңғы нәтижені аламыз

ШЫҒУ = P+I+D

Р бөлігінің арқасында робот ауытқуға пропорционалды тұрақты позицияны ала алады. I бөлім қателік аймағы мен уақыт графигін есептейді. Сондықтан ол роботты тұрақты позицияға дәл жеткізуге тырысады. D бөлігі көлбеуді уақыт пен қателік графигімен өлшейді. Егер қате жоғарыласа, бұл мән оң болады. Егер қате төмендесе, бұл мән теріс болады. Осыған байланысты, робот тұрақты позицияға ауысқанда, реакция жылдамдығы төмендейді және бұл қажетсіз асып кетуді жоюға көмектеседі. Сіз PID теориясы туралы толығырақ төменде көрсетілген сілтемеден біле аласыз.

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

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

3 -қадам: Жабдықты орнату

Жабдықты орнату
Жабдықты орнату

Енді бұл аппараттық құралдарды орнату бөлігі. Роботтың дизайны сізге байланысты. Сіз роботтың корпусын жасаған кезде оны қозғалтқыш осінде орналасқан тік оське қатысты симметриялы түрде қарастыруыңыз керек. Батарея жиынтығы төменде орналасқан. Сондықтан роботты теңестіру оңай. Біздің дизайнда біз Magicbit тақтасын денеге тігінен бекітеміз. Біз 12 вольтты екі қозғалтқышты қолдандық. Бірақ сіз кез келген қозғалтқышты қолдана аласыз. Бұл сіздің роботтың өлшеміне байланысты.

Біз схема туралы сөйлескенде, ол 7.4V Lipo батареясымен жұмыс істейді. Magicbit 5В қуат көзін қолданды. Батарея кернеуін 5В -қа реттеу үшін біз 7805 реттегішті қолдандық. Magicbit -тің кейінгі нұсқаларында бұл реттеуші қажет емес. Өйткені ол 12 В -қа дейін қуат береді. Біз мотор жүргізушісі үшін 7.4В тікелей жеткіземіз.

Барлық компоненттерді төмендегі схемаға сәйкес қосыңыз.

4 -қадам: Бағдарламалық қамтамасыз етуді орнату

Кодта біз PID шығысын есептеу үшін PID кітапханасын қолдандық.

Оны жүктеу үшін келесі сілтемеге өтіңіз.

www.arduinolibraries.info/libraries/pid

Оның соңғы нұсқасын жүктеп алыңыз.

Сенсордың көрсеткіштерін жақсарту үшін біз DMP кітапханасын қолдандық. DMP цифрлық қозғалыс процесін білдіреді. Бұл MPU6050 кіріктірілген мүмкіндігі. Бұл чипте қозғалыс процесінің бірлігі бар. Сондықтан оқу мен талдау қажет. Ол микроконтроллерге дыбыссыз дәл шығуларды шығарады (бұл жағдайда Magicbit (ESP32)). Бірақ микроконтроллер жағында бұл көрсеткіштерді алу және бұрышты есептеу үшін көптеген жұмыстар бар. Біз MPU6050 DMP кітапханасын қолдандық. Оны төмендегі сілтеме бойынша жүктеп алыңыз.

github.com/ElectronicCats/mpu6050

Кітапханаларды орнату үшін Arduino мәзірінде құралдар-> кітапхананы қосу-> add.zip кітапханасына өтіп, жүктелген кітапхана файлын таңдаңыз.

Кодта белгіленген нүктенің бұрышын дұрыс өзгерту керек. PID тұрақты мәндері роботтан роботқа әр түрлі. Сондықтан оны реттеу кезінде алдымен Ki және Kd мәндерін нөлге орнатыңыз, содан кейін реакция жылдамдығы жоғарылағанша Kp арттырыңыз. Kp -тің көп болуы артық жүктемелерге әкеледі. Содан кейін Kd мәнін арттырыңыз. Оны әрқашан аз мөлшерде көбейтіңіз. Бұл мән әдетте басқа мәндерге қарағанда төмен. Енді Ki -ді тұрақтылық жақсы болғанша көбейтіңіз.

Дұрыс COM портын таңдап, тақтаға. кодты жүктеңіз. Енді сіз DIY роботымен ойнай аласыз.

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

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

6 -қадам: код

#қосу

#қосу «I2Cdev.h» #include «MPU6050_6Axis_MotionApps20.h» #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include «Wire.h» #endif MPU6050 mpu; bool dmpReady = жалған; // егер DMP init сәтті болса, true орнатыңыз 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]; // [аю, қадам, ролл] жаяу/қадам/орама контейнер және ауырлық векторы қос түпнұсқаSetpoint = 172.5; қос нүкте = түпнұсқалық нүкте; қос қозғалысAngleOffset = 0.1; қос кіріс, шығыс; int moveState = 0; double Kp = 23; // P орнатыңыз бірінші рет екі есе Kd = 0,8; // бұл мән әдетте кіші екі еселенген Ki = 300; // бұл мән PID pid тұрақтылығының жақсы болуы үшін жоғары болуы керек (& кіріс, & шығыс, & белгіленген нүкте, Kp, Ki, Kd, // DIDECT); // pid initialize int motL1 = 26; // int motL2 = 2 қозғалтқышы үшін 4 істікше; int motR1 = 27; int motR2 = 4; тұрақсыз bool mpuInterrupt = false; // MPU үзу түйреуішінің жоғары бос орынға жеткенін көрсетеді dmpDataReady () {mpuInterrupt = true; } void setup () {ledcSetup (0, 20000, 8); // pwm орнату 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 (AUTOMATIC) орнату; pid. SetSampleTime (10); pid. SetOutputLimits (-255, 255); } басқа {// ҚАТЕ! // 1 = жадтың бастапқы жүктелмеуі // 2 = DMP конфигурациясының жаңартулары сәтсіз аяқталды // (егер ол бұзылатын болса, әдетте код 1 болады) Serial.print (F («DMP инициализациясы сәтсіз аяқталды (код»)); сериялық. басып шығару (devStatus); Serial.println (F («)»)); }} void loop () {// егер бағдарламалау сәтсіз болса, (! dmpReady) қайтарылса, ештеңе жасауға тырыспаңыз; // (! mpuInterrupt && fifoCount <packetSize) {pid. Compute (); // осы уақыт кезеңі деректерді жүктеу үшін пайдаланылады, сондықтан оны басқа есептеулер үшін пайдалануға болады motorSpeed (шығару); } // үзіліс жалаушасын қалпына келтіру және 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); // эулер бұрыштары 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;}} бос қозғалтқыш жылдамдығы (int PWM) {float L1, L2, R1, R2; егер (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) тең болғанға дейін төмендетеміз;

}

Ұсынылған: