Ç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ük | Uygun olduğu yer |
|---|---|---|
| 3 | Çok kaba | Sadece öğrenme amaçlı, yavaş robot |
| 5 | Kabul edilebilir | İlk robot, orta hız |
| 8 | İyi | Yarışma başlangıç seviyesi |
| 12–16 | Yüksek | Yü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.
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);
}
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.
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:
- Ki = 0, Kd = 0 yapın. Taban hızı düşük tutun.
- Kp’yi artırın robot çizgiyi takip edene kadar. Biraz zikzak yapması normal.
- Kp’yi salınım başlayana kadar yükseltin, sonra %20 geri çekin.
- Kd’yi ekleyin ve salınım sönene kadar artırın. Kd tipik olarak Kp’nin 5–20 katıdır.
- Taban hızı artırın. Robot bozulursa Kd’yi biraz daha yükseltin.
- 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.
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.
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ı:
- Uzun düz bölüm: Maksimum hızı test etmek için.
- Geniş viraj: Yüksek hızda kararlılık.
- Keskin 90 derece dönüş: Sensör dizisi genişliğinin sınavı.
- S virajı: Robotun ne kadar hızlı yön değiştirebildiği.
- Kesişim: Özel durum kodunun testi.
- 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:
| Deneme | Kp | Kd | Taban hız | Tur süresi | Sonuç |
|---|---|---|---|---|---|
| 1 | 0,08 | 1,2 | 140 | 18,4 s | Kararlı |
| 2 | 0,08 | 1,2 | 170 | 15,1 s | Keskin virajda çıktı |
| 3 | 0,08 | 2,0 | 170 | 15,3 s | Kararlı |
| 4 | 0,10 | 2,0 | 190 | 13,8 s | Hafif 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
- Kalibrasyon yapmamak. En sık ve en pahalı hata.
- Sensör yüksekliğinin değişmesi. Esneyen bir şasi, kodda çözemeyeceğiniz gürültü üretir.
- Ki katsayısını büyük vermek. Robot çizgi etrafında giderek büyüyen salınıma girer.
- Motor sürücüyü hesaba katmamak. PWM 255 verdiğinizde motorun gerçekten tam güç aldığından emin olun.
- 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
0Henüz yorum yok. İlk yorumu sen yaz!