MODÜL 07 DERS 6 / 6 · 60 DK

Görevler: robot tek başına parkuru geçsin

Bu modül boyunca robotuna adım adım kendi başına hareket etmeyi öğrettin. Otonom fazını açtın, hareketleri fazlara böldün, beklemeyi delay yerine geçen zamanı ölçerek kurdun, bir metrenin kaç saniye sürdüğünü ölçüp katsayıya çevirdin ve değişkenlerini her başta sıfırlayıp telemetriyle izledin. Bugün bunların hepsini tek bir işte birleştiriyorsun: robotun, sen ona hiç dokunmadan bir parkuru geçecek ve bir hedefte duracak. Bu ders bir sınav değil, bir usta günü. Yeni bir kavram yok; olanı en iyi ayarlayan kazanacak. Kural basit: bant parkurda robotu hedefe en yakın durduran kişi birinci olur. Üç deneme hakkın var ve her denemeden sonra kodunu düzeltebilirsin.

Kanca: kod aynı, sonuç neden farklı? (10 dk)

🎬 VİDEO · kanca · 50 sn · aynı robot ve aynı otonom kod iki kez çalışıyor. İlk turda pil dolu, robot hedef bandının tam üstünde duruyor. İkinci turda tek fark pil yarıya inmiş; robot aynı kodla hedefin bir karış gerisinde kalıyor. Kimse kumandaya dokunmuyor, kod değişmiyor.

Videoyu dikkatle izle. Robot aynı, yazılım aynı, yol aynı. Kimse tek bir satır değiştirmedi, kimse kumandaya dokunmadı. Ama robot iki turda aynı yerde durmadı. İlk turda hedefi tam tutturdu, ikinci turda geride kaldı. Değişen tek şey pildi: ilk turda doluydu, ikincide yarıya inmişti.

Sınıfça bir dakika tartışın, önce tahmin edin:

Kesin cevabı ana etkinlikten sonra koyacağız. Şimdilik şu kadarını aklında tut: senin robotun mesafeyi bir cetvelle ölçmüyor. Ne kadar ilerlediğini bilmiyor; sadece ne kadar süre motor çevirdiğini biliyor. Pil zayıfsa aynı sürede tekerlek daha yavaş döner, robot daha az yol alır. Bugün tam da bu yüzden üç deneme hakkın var: her turda robotunu o günün piline ve zeminine göre yeniden ayarlayacaksın.

Ana etkinlik: parkur yarışı, üç deneme (20 dk)

Önce sahayı kurun. Yere bantla basit bir parkur çizin: bir başlangıç çizgisi, düz bir yol, bir dönüş köşesi, sonra ikinci bir düz yol ve en sonda bir hedef çizgisi. Bütün robotlar aynı parkuru kullanır. Robotun görevi başlangıçtan çıkıp köşeyi dönmek ve burnunu hedef çizgisine olabildiğince yakın durdurmaktır. Çizgiyi geçmek de, çizgiye ulaşamamak da seni hedeften uzaklaştırır; amaç tam üstünde durmaktır.

Robotunda zaten kalibrasyon dersinden gelen otonom kodun var. Parkuru senin rotana göre fazlara dizersin. Kodun iskeleti şöyle görünür; sayılar senin parkuruna ve senin ölçtüğün katsayılara göre değişir:

const int SOL_RPWM = 16, SOL_LPWM = 17;   // sol motorun iki sinyal pini
const int SAG_RPWM = 18, SAG_LPWM = 19;   // sag motorun iki sinyal pini

// kalibrasyon dersinde KENDI olctugun katsayilar
const float SANIYE_PER_METRE  = 2.40f;   // 0.6 gucte 1 metre kac saniye surer
const float SANIYE_PER_DERECE = 0.012f;  // 0.5 donuste 1 derece kac saniye surer

// parkurun senin olctugun degerleri
const float ILK_YOL   = 1.20f;   // baslangictan koseye kac metre
const float DONUS_ACI = 90.0f;   // kosede kac derece donulecek
const float SON_YOL   = 0.80f;   // koseden hedefe kac metre

int faz = 0;
unsigned long fazBasi = 0;

void autonomousInit() {
  faz = 0;                 // her baslangicta fazi sifirla
  fazBasi = millis();      // ve zaman sayacini sifirla
}

void autonomousLoop() {
  unsigned long gecen = millis() - fazBasi;

  if (faz == 0) {                                   // ilk duz yol
    surSasi(0.6f, 0.0f);
    if (gecen > (unsigned long)(ILK_YOL * SANIYE_PER_METRE * 1000)) {
      faz = 1; fazBasi = millis();
    }
  } else if (faz == 1) {                            // kosede saga don
    surSasi(0.0f, 0.5f);
    if (gecen > (unsigned long)(DONUS_ACI * SANIYE_PER_DERECE * 1000)) {
      faz = 2; fazBasi = millis();
    }
  } else if (faz == 2) {                            // ikinci duz yol
    surSasi(0.6f, 0.0f);
    if (gecen > (unsigned long)(SON_YOL * SANIYE_PER_METRE * 1000)) {
      faz = 3; fazBasi = millis();
    }
  } else {                                          // hedefte dur
    surSasi(0.0f, 0.0f);
  }

  probot::clearTelemetry();
  probot::printf("faz: %d\n", faz);       // robot su an hangi adimda
  probot::printf("gecen: %lu\n", gecen);  // bu adimda kac ms gectiyi izle
  delay(20);
}

Puan sistemini şimdi kur. Kâğıdının üstüne şu tabloyu çiz. Her denemeden sonra robotun burnunun hedef çizgisine kaç santim uzaklıkta durduğunu mezurayla ölç ve yaz. Küçük sayı iyidir; sıfır en iyisidir.

DenemeHedefe kalan mesafeKısa mı, uzun mu durdu?Ne değiştirdin?
1. deneme... cm(ilk denemede henüz bir şey değiştirmedin)
2. deneme... cm
3. deneme... cm

Denemeler şöyle işler. Her sürücü sırayla robotunu başlangıç çizgisine koyar, Driver Station'da otonomu açar ve Start'a basar. Robota hiç dokunmadan izlersiniz. Robot durunca burnunun hedefe uzaklığını ölçüp tabloya yazarsın. Sonra bilgisayarına dönüp bir sonraki denemeye hazırlanırsın: robot kısa kaldıysa SON_YOL ya da ILK_YOL değerini birazcık büyüt, çizgiyi geçtiyse birazcık küçült; köşede az döndüyse DONUS_ACI'yı artır, çok döndüyse azalt. Üç denemenin sonunda en yakın durduğun mesafe senin yarış puanındır. Sınıfça en küçük mesafeyi tutturan birinci olur.

Kavram köprüsü: robot yolu değil, süreyi sayar (7 dk)

Durup nefeslen. Robotunu ayarladın, şimdi bugün gördüğün şeyin adını koyalım.

Senin robotun açık döngü ile çalışıyor. Bu şu demek: robot bir komut verir ("0.6 güçte ileri çevir") ve sonucun ne olduğuna hiç bakmaz. Gerçekten bir metre gitti mi, yarım metre mi kaldı, tekerlek kaydı mı, bunu bilmez. Sadece senin ölçtüğün süre kadar motoru çevirir, sonra durur. Gözü yoktur; kör bir plan uygular. Bu yüzden kanca videosundaki robot pil zayıfken geride kaldı: aynı süre kadar çevirdi ama zayıf pil tekerleği daha yavaş döndürdü, o yüzden daha az yol aldı. Kod yanlış değildi; kodun dünyası değişmişti.

Bir şeyi daha adlandıralım: sapma birikir. İlk yolda robot birazcık sola kaçtıysa, köşeye zaten eğik gelir; dönüşten sonra bu eğiklik büyür ve ikinci yolun sonunda hedeften iyice şaşar. Her fazın küçük hatası bir sonrakine eklenir. Rota ne kadar uzunsa birikme o kadar büyük olur. İşte bu yüzden kısa parkurlar uzun parkurlardan daha güvenilirdir.

Şimdi kancadaki soruların cevabı net: robot mesafeyi metreyle değil, süreyle ölçüyor. Senin SANIYE_PER_METRE katsayın "bu pil, bu zemin, bu güçte bir metre şu kadar saniye" demek. Pil ya da zemin değişince o katsayı da değişir, ama kodun içindeki sayı aynı kalır; işte sapma buradan doğar. Dürüst ol: bu yöntem bir tahmindir. İyi bir tahmindir, ölçerek düzeltilebilir bir tahmindir, ama bir tahmindir. Robotlar bir gün tekerleğin gerçekten kaç tur döndüğünü sayan parçalarla bu tahmini gerçek ölçüme çevirir; sen şimdilik en iyi tahminciyi kuruyorsun ve onu her denemede biraz daha keskinleştiriyorsun.

Uygulama: rotaya bir iş ekle (15 dk)

Bir parkuru geçmek güzel, ama otonomun asıl gücü robotun tek başına bir yapmasıdır. Şimdi rotana bir görev fazı ekleyeceksin: robot hedefe varınca durmakla kalmasın, orada mekanizmasını çevirip küçük bir iş yapsın. Böylece bu modülde öğrendiğin otonomu, daha önceki modüllerden gelen sürüş ve mekanizmayla tek bir planda birleştirirsin.

Mekanizma motorun için pinleri ve mekanizma dersinden gelen kontrol satırını kullanırsın. Hedefte durduktan sonra gelen yeni bir faz, mekanizmayı bir süre çevirir ve sonra durdurur:

const int MEK_RPWM = 21, MEK_LPWM = 22;   // mekanizma motorunun iki sinyal pini

// ... yukaridaki fazlar aynen durur, "hedefte dur" fazini boyle degistir:

  } else if (faz == 3) {                     // hedefte once dur
    surSasi(0.0f, 0.0f);
    if (gecen > 500) { faz = 4; fazBasi = millis(); }   // yarim saniye bekle
  } else if (faz == 4) {                     // mekanizmayi cevir (isi yap)
    surMotor(MEK_RPWM, MEK_LPWM, 0.6f);
    if (gecen > 1500) { faz = 5; fazBasi = millis(); }
  } else {                                   // her seyi durdur
    surSasi(0.0f, 0.0f);
    surMotor(MEK_RPWM, MEK_LPWM, 0.0f);
  }

Dikkat et: mekanizma fazında da delay ile uzun uzun beklemiyorsun. Faz makinen her turda autonomousLoop'a girip çıkıyor, arada telemetri yazıyor ve süreyi geçen zamandan ölçüyor. Bir güvenlik nedeni var: loop uzun süre bloke olursa robotun güvenliği devreye girer ve robot durur. Mekanizmayı uçta zorlama da; motor inlerse ve akım artarsa bekleme süresini kısalt. İşi biten robot hem sürüşünü hem mekanizmasını sıfıra çeker; bu da otonomun altın kuralıdır: plan bitince her şey durur.

Şimdi pil farkını gözle. Aynı kodu önce dolu, sonra yarıya inmiş pille çalıştır. Robotun aynı yolun sonunda nerede durduğunu iki kez ölç ve karşılaştır. Zayıf pille robot büyük olasılıkla geride kalacak; mekanizma da daha yavaş dönecek. Bunu gördüğünde açık döngünün sınırını kendi gözünle görmüş olursun.

Pekiştirme ve öz-değerlendirme (7 dk)

Görev bitti, şimdi kendine karşı dürüst ol. Kimse not vermiyor; gelişimini sen ölçüyorsun. Her satır için sana en uygun sütunu işaretle.

SoruBaşlangıçGelişiyorUstalaştım
Robotu fazlara bölünmüş bir rotayı tek başına geçirebiliyorumTek hareket yaptırabildimRotayı fazladım ama sapıyorRobot rotayı düzgün geçiyor
Kalibrasyon katsayısını denemeyle düzeltebiliyorumRastgele değer denedimKısa/uzun kalınca yönü buldumAz denemede hedefi tutturuyorum
Robotun süreyi saydığını, mesafeyi ölçmediğini anlatabiliyorumEmin değilimFarkı biliyorumPil/zemin etkisini de açıklıyorum
Pilin dolu ve zayıf hâlinin farkını görüp anlatabiliyorumFark etmedimFarkı gördümNedenini açık döngüyle açıklıyorum
Sürüş, mekanizma ve otonomu tek planda birleştirdimSadece sürüşMekanizma fazı ekledimTam görevi tek başına yaptırdım

Günlük hayat bağı: Bugün öğrendiğin şey sadece robotla ilgili değil. Bir çamaşır makinesi, içeride kaç kilo çamaşır olduğunu bilmeden önceden ayarlanmış bir süre kadar döner; program aynıdır ama sonuç yüke göre biraz değişir. Bir fırın, yemeğin gerçekten piştiğine bakmadan süreyi sayar; o yüzden tarif "180 derecede 25 dakika" der ama sen yine de kontrol edersin. Hepsi senin robotun gibi açık döngüdür: önceden yazılmış bir plan, sonucu ölçmeden uygulanır. Bir planın ne zaman yeterince iyi, ne zaman kontrol gerektirdiğini bilmek, sadece robotların değil senin de becerindir.

Modül kontrol listesi

Bu ders otonom modülünün sonu. Şu satırların hepsine gönül rahatlığıyla evet diyebiliyorsan modülü bitirdin sayılır:

Erken bitirene ek görev

Yarışı erken bitirdiysen boş durma, iki meydan okuma seni bekliyor: