Kerem Öz

Çizgi İzleyen Robot Yapımı: Sensör Dizisi, PID ve Hız Ayarı

Çizgi izleyen robot yapımının tüm adımları: sensör dizisi tasarımı, kalibrasyon, ağırlıklı ortalama ile hata hesabı, PID ayarı, viraj stratejisi ve hız artırma yöntemleri.

Çizgi İzleyen Robot Yapımı: Sensör Dizisi, PID ve Hız Ayarı
Şek. 1 Çizgi İzleyen Robot Yapımı: Sensör Dizisi, PID ve Hız Ayarı

Çizgi izleyen robot, robotik öğrenmenin en verimli projesi. Sebebi şu: tek bir görev üzerinden sensör okuma, gürültü filtreleme, kontrol teorisi ve motor sürüşünü aynı anda öğreniyorsunuz. Basit versiyonu bir öğleden sonrada çalışır; yarışma seviyesine çıkarmak ise aylar sürer.

Bu rehberde çizgi izleyen robot yapımını iki katmanda anlatıyorum. Önce çalışan bir robotu ayağa kaldırıyoruz; sonra onu hızlandıran şeyleri, yani sensör dizisi tasarımını, kalibrasyonu ve PID ayarını tek tek ele alıyoruz.

Çalışma mantığı: robot aslında ne ölçüyor

Çizgi izleyen robotun tek işi var: çizginin robotun merkezine göre nerede olduğunu sürekli ölçmek ve bu farkı sıfıra indirmeye çalışmak. Bu farka hata diyoruz.

Robot çizginin tam üstündeyse hata sıfırdır. Çizgi sağa kaydıysa hata pozitif, sola kaydıysa negatif olur. Motorların işi bu hatayı kapatmak. Kontrol algoritmasının tamamı bu tek sayının etrafında dönüyor.

Kızılötesi yansımalı sensör nasıl çalışır

Kullandığımız sensörler (QRE1113, TCRT5000, QTR dizileri) bir kızılötesi LED ile bir fototransistörden oluşur. LED zemine ışık gönderir, fototransistör geri yansıyanı ölçer:

  • Beyaz zemin ışığı çok yansıtır → sensör düşük direnç okur.
  • Siyah çizgi ışığı yutar → sensör yüksek direnç okur.

Aradaki bu fark, tüm sistemin dayandığı sinyal. Fark ne kadar büyükse robot o kadar kararlı olur — bu yüzden pist malzemesi ve sensör yüksekliği, kod kadar önemlidir.

Sensör dizisi tasarımı

Sensör dizisi, robotun gözü. Buradaki üç karar performansı doğrudan belirliyor.

1. Sensör sayısı

Sensör sayısıÇözünürlükUygun olduğu yer
3Çok kabaSadece öğrenme amaçlı, yavaş robot
5Kabul edilebilirİlk robot, orta hız
8İyiYarışma başlangıç seviyesi
12–16YüksekYüksek hız, keskin viraj

Sensör sayısını artırmak sadece hassasiyeti değil, robotun çizgiyi kaybetmeden algılayabildiği açıyı da artırır. 5 sensörle keskin bir 90 derece virajda çizgi tamamen dizinin dışına çıkabilir; 12 sensörle çıkmaz.

2. Sensörler arası mesafe

Genel kural: sensörler arası mesafe çizgi genişliğinin yarısı kadar olmalı. Standart yarışma çizgisi 19 mm ise sensör aralığı 8–10 mm iyidir. Bu sayede çizgi her zaman en az iki sensörü aynı anda etkiler ve ara konumları hesaplayabilirsiniz.

3. Diziden tekerleğe mesafe

Burası çoğu robotta yanlış yapılıyor. Sensör dizisi tekerlek ekseninden ne kadar öndeyse, robot virajı o kadar erken görür — bu iyi. Ama çok öndeyse, robotun dönüşü diziyi çizgiden fazla savurur — bu kötü.

Pratik aralık 4–8 cm. Hızlı robotlarda öne, yavaş ve keskin virajlı pistlerde geriye kaydırın.

Çizgi izleyen robotun altındaki kızılötesi sensör dizisi ve zeminle arasındaki boşluk
Şek. 2 — Sensör dizisinin zeminden yüksekliği 3–5 mm’de sabit kalmalı. Şasi esnerse okuma da değişir.

Kalibrasyon: atlanırsa hiçbir şey çalışmaz

Ham sensör değerleri her ortamda farklıdır. Atölyenizde 200–800 aralığında okuyan sensör, yarışma salonunda 350–700 okuyabilir. Sabit eşik yazarsanız robot orada çalışmaz.

Çözüm, açılışta kalibrasyon yapmak: robotu çizginin üzerinde birkaç saniye sağa sola süpürün, her sensör için gördüğü en küçük ve en büyük değeri kaydedin.

void kalibreEt() {
  for (int i = 0; i < SENSOR_SAYISI; i++) {
    minDeger[i] = 1023;
    maxDeger[i] = 0;
  }
  unsigned long baslangic = millis();
  while (millis() - baslangic < 3000) {   // 3 saniye süpür
    sagaSolaSalin();
    for (int i = 0; i < SENSOR_SAYISI; i++) {
      int v = analogRead(sensorPin[i]);
      if (v < minDeger[i]) minDeger[i] = v;
      if (v > maxDeger[i]) maxDeger[i] = v;
    }
  }
  motorDur();
}

Sonrasında her okumayı 0–1000 aralığına normalize edersiniz:

int normalize(int ham, int i) {
  long d = (long)(ham - minDeger[i]) * 1000 / (maxDeger[i] - minDeger[i]);
  return constrain(d, 0, 1000);
}
Saha notu

Kalibrasyonu her yarışmada, hatta ışık değiştiğinde her turda tekrarlayın. Kalibrasyon verilerini EEPROM’a kaydedip bir sonraki açılışta kullanmak cazip görünür ama ortam değiştiğinde eski veri robotu yanıltır.

Hata hesabı: ağırlıklı ortalama

Sensör değerlerinden tek bir konum sayısı üretmenin en iyi yolu ağırlıklı ortalamadır. Her sensöre bir konum ağırlığı verirsiniz ve okunan değerlere göre ortalamayı alırsınız.

long konumHesapla() {
  long toplamAgirlik = 0;
  long toplamDeger   = 0;

  for (int i = 0; i < SENSOR_SAYISI; i++) {
    int v = normalize(analogRead(sensorPin[i]), i);
    toplamAgirlik += (long)v * (i * 1000);  // sensörün konum ağırlığı
    toplamDeger   += v;
  }

  if (toplamDeger < 50) return sonKonum;   // çizgi kayboldu
  sonKonum = toplamAgirlik / toplamDeger;
  return sonKonum;
}

8 sensörlü bir dizide merkez değeri 3500 olur. Hata da basitçe:

int hata = konumHesapla() - 3500;

Bu hesabın nasıl çalıştığını görmek için aşağıdaki modülde çizgiyi kaydırın. Sensörlerin okuduğu değerlerin nasıl tek bir konum sayısına dönüştüğünü ve çizgi diziden çıktığında ne olduğunu izleyin.

Etkileşimli sensör dizisi — bu bölüm JavaScript ile çalışır.

sonKonum değişkeni önemli: çizgi tamamen kaybolduğunda robot son bilinen yöne devam eder. Bu tek satır, boşluklu pistlerde robotu kurtarır.

PID kontrol: hatayı motora çevirmek

Elimizde bir hata var; şimdi bunu motor hızına çevirmemiz gerekiyor. PID kontrolün üç bileşeni bunu üç farklı açıdan yapar:

  • P (oransal): Hata ne kadar büyükse düzeltme o kadar büyük. Ana itici güç.
  • I (integral): Zamanla biriken küçük hataları toplar. Çizgi izleyende genelde gereksiz, hatta zararlı.
  • D (türev): Hatanın değişim hızına bakar. Salınımı söndürür, robot virajı önceden karşılar.
int  sonHata = 0;
long integral = 0;

void loop() {
  int hata = konumHesapla() - 3500;

  integral += hata;
  integral = constrain(integral, -10000, 10000);   // integral şişmesini engelle

  int turev = hata - sonHata;
  sonHata   = hata;

  int duzeltme = (Kp * hata) + (Ki * integral) + (Kd * turev);

  int solHiz  = constrain(TABAN_HIZ + duzeltme, 0, 255);
  int sagHiz  = constrain(TABAN_HIZ - duzeltme, 0, 255);

  motorSur(solHiz, sagHiz);
}

Katsayıları sırayla ayarlamak

PID ayarı deneme yanılma işidir ama rastgele değil. Şu sırayı izleyin:

  1. Ki = 0, Kd = 0 yapın. Taban hızı düşük tutun.
  2. Kp’yi artırın robot çizgiyi takip edene kadar. Biraz zikzak yapması normal.
  3. Kp’yi salınım başlayana kadar yükseltin, sonra %20 geri çekin.
  4. Kd’yi ekleyin ve salınım sönene kadar artırın. Kd tipik olarak Kp’nin 5–20 katıdır.
  5. Taban hızı artırın. Robot bozulursa Kd’yi biraz daha yükseltin.
  6. Ki’yi en son, çok küçük değerlerle (0.0001 mertebesi) deneyin. Fayda görmezseniz sıfırda bırakın.

PID’in matematiğini ve her katsayının fiziksel karşılığını daha derin merak ediyorsanız, konuyu tek başına ele aldığım PID kontrol rehberine bakın.

Dikkat

Katsayıları her seferinde tek tek değiştirin ve değişikliği bir deftere yazın. Aynı anda iki katsayıyı oynatınca hangisinin işe yaradığını asla anlayamazsınız. Bluetooth veya potansiyometre ile canlı ayar yapabilmek bu süreci saatlerce kısaltır.

Hızı artırmanın yolları

Çalışan bir robotunuz olduğunda asıl mühendislik başlıyor: aynı pisti daha hızlı bitirmek.

Değişken taban hız

Sabit hız yerine, hata büyüdükçe yavaşlayan bir hız kullanın. Düz yolda tam gaz, virajda otomatik fren:

int mutlakHata = abs(hata);
int tabanHiz = map(mutlakHata, 0, 3500, MAKS_HIZ, MIN_HIZ);
tabanHiz = constrain(tabanHiz, MIN_HIZ, MAKS_HIZ);

Bu tek değişiklik, çoğu robotta tur süresini gözle görülür şekilde düşürür.

Motor freni

Keskin virajda iç tekerleği yavaşlatmak yeterli olmayabilir; ters yönde döndürmek gerekir. Sürücü kartınız bunu destekliyorsa, hızın negatif olabilmesine izin verin:

int solHiz = constrain(tabanHiz + duzeltme, -255, 255);
int sagHiz = constrain(tabanHiz - duzeltme, -255, 255);

Mekanik iyileştirmeler

  • Ağırlık merkezini alçaltın. Yüksek robot virajda devrilir veya tekerlek kaldırır.
  • Tekerlek tutuşunu artırın. Silikon tekerlekler viraj hızını doğrudan yükseltir.
  • Ağırlığı azaltın. Atalet düştükçe robot daha hızlı yön değiştirir.
  • Motor sürücüyü büyütün. Akım sınırına takılan sürücü, kodunuz ne kadar iyi olursa olsun hızı sınırlar.

Motor tipi, redüksiyon oranı ve sürücü kartı seçimini motor seçimi rehberinde ayrıntılı karşılaştırdım.

Beyaz zemin üzerine siyah bantla oluşturulmuş çizgi izleyen robot pisti ve keskin viraj
Şek. 3 — Keskin virajlar, sensör dizisi genişliğinin ve viraj öncesi yavaşlamanın gerçek sınavı.

Motor, sürücü ve güç

Kontrol algoritmanız mükemmel olsa bile, komutu zemine aktaramayan bir tahrik sistemi robotu yavaş bırakır. Çizgi izleyende üç bileşen birlikte çalışmalı.

Motor seçimi

Çizgi izleyen, mini sumonun tersine hız odaklı bir kategori. Redüksiyon oranı 1:20 ile 1:50 arasında olmalı; 1:100 gibi güçlü ama yavaş bir motor burada işe yaramaz.

Motorların eşleşmiş olması da önemli. Aynı PWM değerinde farklı hızda dönen iki motor, robotun düz gitmeye çalışırken sürekli sağa ya da sola kaymasına yol açar. Bunu yazılımla düzeltebilirsiniz:

// Sol motor sağdan hızlıysa kalibrasyon katsayısıyla dengele
const float SOL_KATSAYI = 0.94;
const float SAG_KATSAYI = 1.00;

void motorSur(int sol, int sag) {
  analogWrite(SOL_PWM, constrain(sol * SOL_KATSAYI, 0, 255));
  analogWrite(SAG_PWM, constrain(sag * SAG_KATSAYI, 0, 255));
}

Katsayıyı bulmak için robotu düz bir zeminde eşit PWM ile sürün ve hangi tarafa kaydığına bakın.

Sürücü kartının gizli maliyeti

L298N sürücü, motor başına yaklaşık 1,4–2 V gerilim düşürür. 7,4 V’luk bir pilden motorlara sadece 5,5 V ulaşır — yani pilinizin dörtte birini ısıya çevirmiş olursunuz.

MOSFET tabanlı TB6612FNG’de bu kayıp 0,1 V mertebesindedir. Aynı pil, aynı motor, hiçbir kod değişikliği yok — ama robot belirgin şekilde hızlanır. Sürücü karşılaştırmasının tamamı motor seçimi rehberinde.

Gerilim düştükçe davranış değişir

Pil doluyken mükemmel ayarlanmış PID katsayıları, pil yarılandığında fazla yumuşak kalır. Çünkü aynı PWM değeri artık daha az tork üretiyor.

Bunu çözmenin iki yolu var: yarışma boyunca pili hep dolu tutmak (pratik çözüm) veya pil gerilimini ölçüp taban hızı buna göre ölçeklemek (doğru çözüm):

float pilKatsayisi() {
  float v = pilGeriliminiOku();          // ör. 8.4 V tam dolu
  return constrain(8.4 / v, 1.0, 1.35);  // gerilim düştükçe PWM'i artır
}

Pist yapımı ve test düzeni

Robotu ancak test edebildiğiniz kadar iyileştirebilirsiniz. Evde kurulabilecek basit bir pist, ilerlemenizi hızlandıran en büyük yatırım.

Malzeme

  • Zemin: Beyaz, mat MDF levha veya büyük beyaz karton. Parlak yüzey yansıma yapar, sensörü şaşırtır.
  • Çizgi: 19 mm siyah elektrik bandı veya mat siyah izolasyon bandı. Parlak bant kullanmayın.
  • Boyut: En az 150 × 100 cm. Daha küçük pistte gerçek viraj davranışını göremezsiniz.

Piste ne koymalı

Kolay bir oval çizip “çalışıyor” demeyin. Test pistinde şunlar bulunmalı:

  1. Uzun düz bölüm: Maksimum hızı test etmek için.
  2. Geniş viraj: Yüksek hızda kararlılık.
  3. Keskin 90 derece dönüş: Sensör dizisi genişliğinin sınavı.
  4. S virajı: Robotun ne kadar hızlı yön değiştirebildiği.
  5. Kesişim: Özel durum kodunun testi.
  6. Kısa boşluk (2–3 cm): Çizgi kaybı kurtarma davranışı.

Ölçülebilir test

“Daha iyi oldu” yeterli bir değerlendirme değil. Kronometreyle tur süresi tutun ve her ayarı deftere yazın:

DenemeKpKdTaban hızTur süresiSonuç
10,081,214018,4 sKararlı
20,081,217015,1 sKeskin virajda çıktı
30,082,017015,3 sKararlı
40,102,019013,8 sHafif salınım

Bu tablo, üç saatlik ayar çalışmasının hafızası. Onsuz aynı denemeleri tekrar edersiniz.

Özel durumlar

Çizgi kaybı

Robot çizgiyi tamamen kaybederse ne yapacağını bilmeli. En sağlam yöntem, son bilinen hata yönünde dönmeye devam etmek:

if (toplamDeger < 50) {          // hiçbir sensör çizgi görmüyor
  if (sonHata > 0) motorSur(MAKS_HIZ, -MAKS_HIZ);   // sağa ara
  else             motorSur(-MAKS_HIZ, MAKS_HIZ);   // sola ara
  return;
}

Kesişimler ve 90 derece dönüşler

Pistte kesişim varsa tüm sensörler aynı anda siyah görür. Bunu ayrı bir durum olarak yakalayın, yoksa ağırlıklı ortalama anlamsız bir merkez değeri üretir:

bool kesisimMi() {
  int siyahSayisi = 0;
  for (int i = 0; i < SENSOR_SAYISI; i++) {
    if (normalize(analogRead(sensorPin[i]), i) > 700) siyahSayisi++;
  }
  return siyahSayisi >= SENSOR_SAYISI - 1;
}

Sık yapılan hatalar

  1. Kalibrasyon yapmamak. En sık ve en pahalı hata.
  2. Sensör yüksekliğinin değişmesi. Esneyen bir şasi, kodda çözemeyeceğiniz gürültü üretir.
  3. Ki katsayısını büyük vermek. Robot çizgi etrafında giderek büyüyen salınıma girer.
  4. Motor sürücüyü hesaba katmamak. PWM 255 verdiğinizde motorun gerçekten tam güç aldığından emin olun.
  5. Sadece düz pistte test etmek. Robotu keskin viraj, kesişim ve boşluk içeren bir pistte deneyin.

Sonraki adım

Çizgi izleyen robot bittiğinde elinizde sadece bir robot değil, kontrol sistemi kurma pratiği olur. Aynı PID mantığı otonom araçlarda direksiyon kontrolünde, dengeleme robotlarında ve motor hız kontrolünde birebir çalışıyor.

Arduino tarafında temelleri güçlendirmek isterseniz Arduino başlangıç rehberi, kartınızı yükseltmeyi düşünüyorsanız ESP32 mi Arduino mu yazısı iyi bir devam noktası.

Sıkça Sorulan Sorular

Çizgi izleyen robotta kaç sensör kullanmalıyım?

Başlangıç için 5 sensör yeterlidir ve öğrenmesi kolaydır. Yarışma hızına çıkmak istiyorsanız 8–12 sensörlü dizi kullanın: daha fazla sensör, çizginin konumunu daha hassas ölçmenizi ve dolayısıyla daha yüksek hızda kararlı kalmanızı sağlar.

Çizgi izleyen robot neden virajda çizgiden çıkıyor?

Üç tipik sebep var: hız virajın yarıçapına göre çok yüksek, türev (D) katsayısı düşük olduğu için robot geç tepki veriyor, ya da sensör dizisi tekerlek ekseninden çok uzakta. Önce hızı düşürüp kararlılığı doğrulayın, sonra D katsayısını artırın.

PID katsayılarını nasıl ayarlarım?

Sırayla ilerleyin: önce Ki ve Kd sıfırken Kp’yi robot çizgiyi takip edip hafifçe salınana kadar artırın. Sonra Kd’yi bu salınım sönene kadar yükseltin. Ki’yi en son ve çok küçük değerlerle ekleyin; çizgi izleyende çoğu zaman Ki=0 en iyi sonucu verir.

Kızılötesi sensör mü kamera mı kullanmalıyım?

Klasik çizgi izleyen yarışmaları için kızılötesi yansımalı sensör dizisi doğru tercihtir: milisaniyenin altında yanıt verir ve işlemci yükü yok denecek kadar azdır. Kamera, çizgi dışında nesne veya işaret tanıma gerektiren otonom görevler için anlamlıdır.

Ortam ışığı sensörleri etkiliyor, ne yapmalıyım?

Sensör dizisini bir siperlikle gölgeleyin, zeminden yüksekliği 3–5 mm’de sabitleyin ve her yarışmadan önce mutlaka o pistin üzerinde kalibrasyon yapın. Sabit eşik değeri yerine kalibrasyonla bulunan min/max değerlere göre normalizasyon kullanın.

Yorumlar

0

Henüz yorum yok. İlk yorumu sen yaz!

Yorum Yaz

E-posta adresiniz yayınlanmaz, sadece site sahibi görebilir.