PRJ-04Oson45 daqiqa8 ta detalSimulyatorda bor

Masofa saqlovchi robot

Mashina oldidagi narsadan 20 sm narida turadi va narsa siljisa, unga ergashadi. Bu birinchi proporsional rostlagichingiz (P-rostlagich): uni Serial Monitor oynasini kuzatib sozlaysiz.

Robot nima qiladi

Robot oldidagi narsadan 20 sm masofani saqlaydi: narsa uzoqlashsa, unga yaqinlashadi, narsa yaqinlashsa, orqaga yuradi.

VideoYouTubeʼda

Bu robotning oldida kitob tutib turing: robot kitobga yaqinlashadi va undan 20 sm narida toʻxtaydi. Kitobni uzoqlashtirsangiz, robot unga ergashadi. Yaqinlashtirsangiz, robot orqaga yuradi. Robot tezligini masofa 20 sm dan qancha farq qilishiga qarab tanlaydi: uzoqda boʻlsa tez, deyarli yetib kelganda sekin yuradi. Bu proporsional rostlagich yoki P-rostlagich deyiladi. Texnikada tezlikni, haroratni yoki joylashuvni bir xil ushlab turish uchun shunday rostlagichlar ishlatiladi. Xato va kuchaytirish koeffitsiyenti nimani bildirishini, robotga nega eng kichik tezlik va oʻlik zona kerakligini hamda kuchaytirish koeffitsiyentini qanday sozlashni oʻrganasiz. Bu oson loyiha, u taxminan 45 daqiqa vaqt oladi.

Nima kerak

Ushbu loyiha uchun detallarHammasi toʻplamda bor: Arduino bilan 2WD robot-mashina toʻplami

Bu toʻsiqni aylanib oʻtuvchi robot bilan bir xil robot: old tomonida HC-SR04 boʻlgan mashina. Faqat sketch yangi. Nishon sifatida qoʻldan koʻra kitob yoki kichik quti yaxshiroq, chunki tekis, qattiq sirtlar kuchliroq aks-sado qaytaradi.

Qanday ishlaydi

HC-SR04 40 kHz tovush yuboradi, devor aks-sadoni qaytaradi, mikrosekundlardagi t vaqt esa masofani beradi: d = t / 58 sm.

Xato: maqsaddan qancha uzoqda

Robot narsadan 20 sm masofada boʻlishni xohlaydi. Bu istalgan masofa maqsad deyiladi, sketchda u TARGET_CM. Har bir oʻlchovdan keyin robot xatoni hisoblaydi:

xato = masofa - 20

30 sm da xato 10 ga teng: robot juda uzoqda va oldinga yurishi kerak. 20 sm da xato 0: robot kerakli joyda turibdi. 15 sm da xato -5: robot juda yaqin va orqaga yurishi kerak.

Kuchaytirish koeffitsiyenti: qanchalik kuchli javob berish

Tezlik xatoni kuchaytirish koeffitsiyenti KP ga koʻpaytirib topiladi, bu sketchda u 12 ga teng:

tezlik = 12 × xato

Katta xato katta tezlik, kichik xato esa kichik tezlik beradi. Shuning uchun robot maqsaddan uzoqda boʻlsa shoshiladi, yaqinlashgan sari esa sekinlashadi.

Haqiqiy motorlar uchun uchta cheklov

  • Eng yuqori tezlik. Tezlik -255 bilan 255 oraligʻida ushlab turiladi. 255 — eng katta PWM (impuls kengligi modulyatsiyasi) qiymati. 42 sm dan 150 sm gacha robot toʻliq tezlikda yuradi.
  • Eng kichik tezlik. Taxminan 90 dan past tezlikda TT motorlar faqat gʻuvillaydi, lekin aylanmaydi. Shuning uchun kichik tezlik 90 gacha, robot orqaga yurganda esa -90 gacha oshiriladi.
  • Oʻlik zona. Xato 2 sm yoki undan kam boʻlsa, yaʼni masofa 18 dan 22 sm gacha boʻlsa, tezlik 0 ga teng. Oʻlik zona boʻlmasa, robot 20 sm atrofida toʻxtovsiz oldinga-orqaga silkinib turardi, chunki har bir oʻlchov biroz farq qiladi, robotning eng kichik tezligi esa 90.

Yana bitta qoida: 150 sm ichida hech narsa boʻlmasa, robot kutib turadi. U xonaning narigi chetidagi devorni quvib ketmaydi.

Masofa Xato 12 × xato Motorlarga yuboriladigan tezlik
10 sm -10 -120 -120: orqaga
17 sm -3 -36 -90: eng kichik tezlikkacha oshirildi
18 dan 22 sm gacha -2 dan 2 gacha 0: oʻlik zona, joyida turadi
25 sm 5 60 90: eng kichik tezlikkacha oshirildi
30 sm 10 120 120
40 sm 20 240 240
60 sm 40 480 255: eng katta qiymat
200 sm 0: 150 sm ichida hech narsa yoʻq, kutadi

KP nimani oʻzgartiradi

  • KP juda kichik, masalan 4: maqsadga yaqin joyda har bir natija 90 dan kichik chiqadi, shuning uchun robot eng kichik tezlikda imillab yuradi. U sust boʻladi va harakatlanayotgan nishondan ortda qoladi.
  • KP juda katta, masalan 30: 9 sm xatoda ham tezlik toʻliq boʻladi. Robot shoshadi, oʻz vaqtida toʻxtay olmaydi, 20 sm dan oʻtib ketadi va orqaga qaytishga majbur boʻladi. Koʻpincha u oldinga-orqaga chayqalib turadi. Bu tebranish deyiladi.
  • KP mos: robot maqsad tomon tez harakatlanadi, sekinlashadi va chayqalmasdan 20 sm atrofida toʻxtaydi.

Nega katta KP da robot chayqaladi? Robot birdaniga toʻxtay olmaydi: u yana bir lahza dumalashda davom etadi, motorlarga esa sekinlashish uchun vaqt kerak. Oʻlik zonada motorlar erkin aylanadi, shuning uchun robot yana biroz dumalab boradi. Bundan tashqari, u soniyasiga taxminan 20 martagina tuzatish kiritadi. KP katta boʻlsa, robot keyingi tuzatishgacha maqsaddan oʻtib ketgan boʻladi.

Yigʻish

1. Simulyatorda robotni tanlang

Robot va uning ulanishi toʻsiqni aylanib oʻtuvchi robotniki bilan bir xil: uni oʻyinda yigʻgan boʻlsangiz, oʻshandan foydalaning. Aks holda oʻyinda boshidanoq bor boʻlgan Obstacle avoider mashinasidan boshlang va uning simlarini 2-qadamdagi jadvaldagidek ulang.

Haqiqiy yigʻishda: toʻsiqni aylanib oʻtuvchi robot loyihasidagi mashinangizdan foydalaning. HC-SR04 tekis turganini va toʻgʻri oldinga qarab turganini tekshiring.

2. Ulanishni tekshiring

QayerdanQayergaNima uchun
Batareya +L298N +12VMotorlar quvvati: toʻrtta AA batareyadan taxminan 6 V
Batareya -L298N GNDBatareya minusi
L298N +5VUno 5VDrayver stabilizatori Unoni quvvatlaydi: taxminan 4,4 V
L298N GNDUno GNDUmumiy yer: signallarga bir xil 0 V kerak
Uno D5L298N ENAChap motor tezligi (PWM); ENA jumperi olib qoʻyilgan
Uno D4L298N IN1Chap motor yoʻnalishi
Uno D7L298N IN2Chap motor yoʻnalishi
Uno D8L298N IN3Oʻng motor yoʻnalishi
Uno D12L298N IN4Oʻng motor yoʻnalishi
Uno D6L298N ENBOʻng motor tezligi (PWM); ENB jumperi olib qoʻyilgan
Chap motor M+L298N OUT1
Chap motor M-L298N OUT2
Oʻng motor M+L298N OUT4Ataylab almashtirilgan: bu motor koʻzgudagidek oʻrnatilgan
Oʻng motor M-L298N OUT3Ataylab almashtirilgan: bu motor koʻzgudagidek oʻrnatilgan
HC-SR04 VCCL298N +5VDatchik uchun 5 V
HC-SR04 GNDUno GNDYer (GND)
Uno D9HC-SR04 TRIGOʻlchashni boshlaydi: 10 mks impuls
Uno D10HC-SR04 ECHOAks-sadoning borib-qaytish vaqtiga teng impuls

Haqiqiy yigʻishda: mashinangiz toʻsiqni aylanib oʻtuvchi robot sifatida ishlayotgan boʻlsa, ulanish toʻgʻri. Faqat yangi sketchni yuklaysiz.

3. Yuklang va sinab koʻring

«Kod» boʻlimini oching, shu sahifadagi KeepDistance sketchini qoʻying, «Tekshirish» tugmasini, keyin «Yuklash» tugmasini bosing.

Haqiqiy yigʻishda: mashinani gʻildiraklari havoda osilib turadigan qilib quti ustiga qoʻying va sketchni yuklang. Serial Monitor (port monitori) oynasini 9600 bod tezlikda oching. Kitobni datchik oldida, undan 35 sm narida tuting: gʻildiraklar oldinga aylanadi, monitorda esa «speed 180» chiqadi. Kitobni taxminan 20 sm gacha yaqinlashtiring, gʻildiraklar toʻxtaydi. 18 sm dan yaqinroqda ular orqaga aylanadi.

4. Robotni ergashtiring

Arenada robotni ishga tushiring va Serial Monitor oynasini oching. Har bir qatorda masofa va tezlik koʻrsatiladi, masalan 35 cm, speed 180. Robot oldida 150 sm ichida hech narsa boʻlmasa, u kutib turadi va «speed 0» deb chiqaradi. Devor yoki quti yetarlicha yaqin boʻlsa, robot unga yaqinlashadi va taxminan 20 sm narida toʻxtaydi.

Haqiqiy yigʻishda: mashinani polga qoʻying va kitobni uning oldida tuting. Sekin orqaga yursangiz, robot sizga ergashadi. Toʻxtasangiz, u ham toʻxtaydi. Kitobni unga tomon yaqinlashtirsangiz, u orqaga yuradi.

5. KP ni sozlang

KP ning 4, 12 va 30 qiymatlarini sinab koʻring va koʻrganlaringizni yuqoridagi «KP nimani oʻzgartiradi» roʻyxati bilan solishtiring. Bir vaqtda faqat bitta sonni oʻzgartiring, yuklang, sinab koʻring va koʻrganingizni yozib qoʻying. Robot joyiga oʻrnashayotganda Serial Monitor oynasini kuzating. Tezlik musbat va manfiy sonlar orasida almashib tursa, robot tebranyapti: KP ni kamaytiring. Tezlik uzoq vaqt 90 yoki -90 da qolib ketsa, robot sust: KP ni oshiring. Chayqalish boshlanadigan qiymatdan biroz pastroq KP ni tanlang.

MIN_SPEED ni ham sozlang. U mashina haqiqatan harakatlanadigan eng kichik tezlik boʻlishi kerak. Uni polda sinab koʻring, chunki u yerda gʻildiraklar robotni koʻtarib yurishi kerak. Motorlar 90 da faqat gʻuvillasa, 100 yoki 110 ni sinab koʻring.

Haqiqiy robotda eng yaxshi KP boshqacha boʻlishi mumkin, chunki batareyalar, pol va motorlar robotning javob berishini oʻzgartiradi.

Kod

KeepDistance.ino
// Keep-distance robot: it stays TARGET_CM away from whatever is in front of it.
// Put your hand in front of it and move: it follows. A proportional (P) controller.
// L298N: ENA -> D5, IN1 -> D4, IN2 -> D7 (left), ENB -> D6, IN3 -> D8, IN4 -> D12 (right)
// HC-SR04: TRIG -> D9, ECHO -> D10

const byte ENA = 5, IN1 = 4, IN2 = 7;
const byte ENB = 6, IN3 = 8, IN4 = 12;
const byte TRIG = 9, ECHO = 10;

const int TARGET_CM = 20;      // the distance to keep
const float KP = 12.0;         // how hard to react: speed per centimetre of error
const int MIN_SPEED = 90;      // below this the motors only hum and do not turn
const int DEADBAND_CM = 2;     // this close to the target is good enough: stand still
const int FAR_CM = 150;        // nothing nearer than this: wait

void setMotor(byte enablePin, byte inA, byte inB, int speed) {
  speed = constrain(speed, -255, 255);
  digitalWrite(inA, speed > 0);
  digitalWrite(inB, speed < 0);
  analogWrite(enablePin, abs(speed));
}

void drive(int left, int right) {
  setMotor(ENA, IN1, IN2, left);
  setMotor(ENB, IN3, IN4, right);
}

int readDistanceCm() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  unsigned long us = pulseIn(ECHO, HIGH, 25000UL);
  if (us == 0) return 400;
  return us / 58;
}

void setup() {
  const byte pins[] = {ENA, IN1, IN2, ENB, IN3, IN4, TRIG};
  for (byte pin : pins) pinMode(pin, OUTPUT);
  pinMode(ECHO, INPUT);
  Serial.begin(9600);
}

void loop() {
  int cm = readDistanceCm();
  int error = cm - TARGET_CM;          // positive: too far, negative: too close
  int speed = 0;

  if (cm <= FAR_CM && abs(error) > DEADBAND_CM) {
    speed = (int)constrain(KP * error, -255.0, 255.0);
    if (abs(speed) < MIN_SPEED) speed = (speed > 0) ? MIN_SPEED : -MIN_SPEED;
  }
  drive(speed, speed);

  Serial.print(cm);
  Serial.print(" cm, speed ");
  Serial.println(speed);
  delay(50);                            // about 20 corrections a second
}

Sozlamalar

const int TARGET_CM = 20;      // the distance to keep
const float KP = 12.0;         // how hard to react: speed per centimetre of error
const int MIN_SPEED = 90;      // below this the motors only hum and do not turn
const int DEADBAND_CM = 2;     // this close to the target is good enough: stand still
const int FAR_CM = 150;        // nothing nearer than this: wait

Rostlagichning barcha beshta soni sketch boshida turadi. KP — float, yaʼni kasr qismi nuqta bilan yoziladigan son, shuning uchun 8.5 kabi qiymatlarni ham sinab koʻrishingiz mumkin.

Rostlagich

  int cm = readDistanceCm();
  int error = cm - TARGET_CM;          // positive: too far, negative: too close
  int speed = 0;

  if (cm <= FAR_CM && abs(error) > DEADBAND_CM) {
    speed = (int)constrain(KP * error, -255.0, 255.0);
    if (abs(speed) < MIN_SPEED) speed = (speed > 0) ? MIN_SPEED : -MIN_SPEED;
  }
  drive(speed, speed);

Tezlik 0 dan boshlanadi. U faqat FAR_CM ichida biror narsa boʻlsa va xato oʻlik zonadan katta boʻlsa oʻzgaradi. KP * error P-rostlagichning oʻzi. constrain() natijani -255 bilan 255 oraligʻida ushlab turadi, (int) esa uni yana butun songa aylantiradi. Keyingi qator kichik tezlikni MIN_SPEED gacha oshiradi va uning ishorasini saqlab qoladi. (speed > 0) ? MIN_SPEED : -MIN_SPEED shuni bildiradi: tezlik musbat boʻlsa, MIN_SPEED olinadi, aks holda -MIN_SPEED olinadi. Nihoyat, drive(speed, speed) ikkala gʻildirakka bir xil tezlik beradi, shuning uchun robot toʻgʻri oldinga yoki orqaga yuradi.

Aks-sado qaytmasa, readDistanceCm() 400 qaytaradi. Bu FAR_CM dan katta, shuning uchun robot kutib turadi.

Chiqarish va vaqt

Serial.print() masofa va tezlikni bitta qatorga yozadi, Serial.println() esa qatorni yakunlaydi. Keyin delay(50) 50 ms kutadi, shuning uchun robot soniyasiga taxminan 20 marta oʻlchaydi va tuzatish kiritadi. readDistanceCm(), setMotor() va drive() toʻsiqni aylanib oʻtuvchi robotdagidek ishlaydi.

Agar ishlamasa

  • Robot umuman qimirlamayapti. Serial Monitor oynasiga qarang. Masofa 150 dan katta boʻlsa, yetarlicha yaqin narsa yoʻq: nishonni yaqinroq keltiring. Masofa 18 dan 22 sm gacha boʻlsa, robot allaqachon kerakli joyda turibdi.
  • Robot nishonga yaqinlashish oʻrniga undan uzoqlashyapti. Gʻildiraklar notoʻgʻri tomonga aylanyapti. Birinchi yurish loyihasidagidek ularni havoda turgan holda tekshiring va orqaga aylanayotgan motorning simlarini almashtiring.
  • Robot oldinga-orqaga chayqalib, hech toʻxtamayapti. KP juda katta: uni kamaytiring. Oʻlik zonani 3 sm gacha kengaytirishingiz ham mumkin.
  • Maqsadga yaqin joyda motorlar gʻuvillayapti, lekin robot qimirlamayapti. MIN_SPEED motorlaringiz yoki batareyalaringiz uchun juda past. Uni oshiring yoki yangi batareyalar soling.
  • Robot 20 sm ga yetmay yoki undan biroz oʻtib toʻxtayapti. Bu odatiy hol. Oʻlik zona 18 dan 22 sm gacha boʻlgan masofaga ruxsat beradi, motorlar oʻchgach esa robot yana biroz dumalab boradi.
  • Masofa sakrab turibdi. Qoʻl — zaif nishon, yumshoq yoki qiya sirtlar esa kam tovush qaytaradi. Kitobni datchikka tekis qaratib tuting. Ultratovush datchiklari qanday koʻrishi haqidagi maqolani oʻqing.
  • Robot yoʻnalishini oʻzgartirganda qayta ishga tushib qolyapti. Oldinga yurishdan orqaga tez oʻtish batareya kuchlanishini pasaytiradi. Robotlar nega qayta ishga tushib qolishi haqidagi maqolani oʻqing.

Keyingi qadamlar

Robotingiz teskari aloqadan foydalanadi: u oʻlchaydi, maqsad bilan solishtiradi va tuzatadi, bu qayta-qayta takrorlanadi. P-rostlagich PID-rostlagichning birinchi qismi. I qismi uzoq vaqt saqlanib qoladigan kichik xatoni yoʻqotadi, D qismi esa xato qanchalik tez oʻzgarayotganiga javob beradi.

Keyin poldagi chiziq boʻylab yuradigan robotni yigʻing: bu chiziq boʻylab yuruvchi robot. Shuningdek, millis() va holatlar darsida koʻrsatilgandek, delay(50) ni millis() taymeri bilan almashtirishingiz mumkin. Datchik haqida koʻproq bilish uchun HC-SR04 darsini oʻqing.

Yanada yaxshilang

  1. TARGET_CM ni avval 10 ga, keyin 40 ga oʻzgartiring. KP ni ham oʻzgartirish kerakmi?
  2. DistanceMeter sketchidagidek, masofani uchta oʻlchovning medianasi bilan silliqlang.
  3. Oʻlik zonada motorlar erkin aylanmasin, tormozlansin: har bir motorning ikkala yoʻnalish pinini HIGH qiling, enable pinini esa 255 ga qoʻying.