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
Arduino Uno R3Simulyatorda bor× 1Narxni doʻkonda koʻring
L298N motor drayveri moduliSimulyatorda bor× 1Narxni doʻkonda koʻring
TT reduktorli motor 1:48, 65 mm gʻildirak bilanSimulyatorda bor× 2Narxni doʻkonda koʻring
4 × AA batareya qutisiSimulyatorda bor× 1Narxni doʻkonda koʻringSharli tayanch 20 mmSimulyatorda bor× 1Narxni doʻkonda koʻring
HC-SR04 ultratovush datchigiSimulyatorda bor× 1Narxni doʻkonda koʻring
Ulash simlari toʻplami× 1Narxni doʻkonda koʻring
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
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
| Qayerdan | Qayerga | Nima uchun |
|---|---|---|
| Batareya + | L298N +12V | Motorlar quvvati: toʻrtta AA batareyadan taxminan 6 V |
| Batareya - | L298N GND | Batareya minusi |
| L298N +5V | Uno 5V | Drayver stabilizatori Unoni quvvatlaydi: taxminan 4,4 V |
| L298N GND | Uno GND | Umumiy yer: signallarga bir xil 0 V kerak |
| Uno D5 | L298N ENA | Chap motor tezligi (PWM); ENA jumperi olib qoʻyilgan |
| Uno D4 | L298N IN1 | Chap motor yoʻnalishi |
| Uno D7 | L298N IN2 | Chap motor yoʻnalishi |
| Uno D8 | L298N IN3 | Oʻng motor yoʻnalishi |
| Uno D12 | L298N IN4 | Oʻng motor yoʻnalishi |
| Uno D6 | L298N ENB | Oʻng motor tezligi (PWM); ENB jumperi olib qoʻyilgan |
| Chap motor M+ | L298N OUT1 | |
| Chap motor M- | L298N OUT2 | |
| Oʻng motor M+ | L298N OUT4 | Ataylab almashtirilgan: bu motor koʻzgudagidek oʻrnatilgan |
| Oʻng motor M- | L298N OUT3 | Ataylab almashtirilgan: bu motor koʻzgudagidek oʻrnatilgan |
| HC-SR04 VCC | L298N +5V | Datchik uchun 5 V |
| HC-SR04 GND | Uno GND | Yer (GND) |
| Uno D9 | HC-SR04 TRIG | Oʻlchashni boshlaydi: 10 mks impuls |
| Uno D10 | HC-SR04 ECHO | Aks-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
// 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: waitRostlagichning 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
- TARGET_CM ni avval 10 ga, keyin 40 ga oʻzgartiring. KP ni ham oʻzgartirish kerakmi?
- DistanceMeter sketchidagidek, masofani uchta oʻlchovning medianasi bilan silliqlang.
- Oʻlik zonada motorlar erkin aylanmasin, tormozlansin: har bir motorning ikkala yoʻnalish pinini HIGH qiling, enable pinini esa 255 ga qoʻying.
