MODÜL 05 DERS 3 / 5 · 60 DK

Yazılım: servoya açı komutu ver, gripper'ı aç-kapat

Kavrayan el (10 dk)

Geçen derslerde robotun kollarını, dişlilerini ve servoya giden kabloyu yerine koydun. Şimdi o gripper'a hayat vereceksin. Bu dersin sonunda bir butona basınca gripper'ın kapanacak, başka bir butonla açılacak; kavrama ve bırakma açılarını da kendin ayarlayacaksın.

Önce bir soru. Bir DC motor, ona güç verdiğin sürece döner; gücü kestiğinde durur ama nerede durduğunu bilemezsin. Peki gripper'ın parmaklarını tam yarıya kadar kapatıp orada tutmak istesen? Sürüş motoruyla bunu yapamazsın; o sadece "dön" ya da "dur" bilir. İşte gripper'daki servo bunun için var.

🎬 VİDEO · kanca · 45 sn · Robot gripper'ı bir cismi yavaşça kavrar, kaldırır, birkaç saniye havada sabit tutar, başka yere bırakır; parmaklar kapandıktan sonra hiç titremeden duruyor

Videoyu izledikten sonra bir arkadaşınla konuş: parmaklar kapandıktan sonra videoda motor sesi duyuyor musun? Cisim havadayken parmaklar geri kaymıyor, olduğu yerde kalıyor. Sence servoya sürekli "kapan" komutu mu gönderiliyor, yoksa bir kez "şu kadar kapan" deyip bırakılıyor mu? Tahminini aklında tut; kodda cevabını bulacağız.

Kodu yükle ve gripper'ı kullan (20 dk)

Önce çalışan bütünü görelim, sonra parçalayacağız. Aşağıdaki kod, senin zaten bildiğin sürüşün üstüne gripper kontrolünü ekler. Sürüş satırları eskisiyle birebir aynı; yeni olan tek şey servoyla ilgili birkaç satır. Robot askıda dursun, ama gripper serbest kalsın ki parmakların açılıp kapandığını görebilesin.

Kodu Arduino IDE'ye olduğu gibi yapıştır ve yükle:

#define PROBOT_WIFI_AP_SSID     "RobotAdi"
#define PROBOT_WIFI_AP_PASSWORD "sifre1234"
#define PROBOT_WIFI_AP_CHANNEL  1
#include <probot.h>

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
const int SERVO_PIN = 4;                  // gripper servosunun sinyal pini

// hazir yardimci: motoru hizina gore surer (-1 geri, 0 dur, +1 ileri)
void surMotor(int rpwm, int lpwm, float hiz) {
  hiz = constrain(hiz, -1.0f, 1.0f);
  if (hiz > 0) { analogWrite(rpwm, (int)(hiz * 255));  analogWrite(lpwm, 0); }
  else         { analogWrite(rpwm, 0);  analogWrite(lpwm, (int)(-hiz * 255)); }
}

// hazir kalip: dereceyi (0-180) servo sinyaline cevirir
void servoAci(float derece) {
  derece = constrain(derece, 0.0f, 180.0f);
  int us = 500 + (int)(derece / 180.0f * 2000);
  ledcWrite(SERVO_PIN, (uint32_t)us * 16383 / 20000);
}

void robotInit() {
  pinMode(SOL_RPWM, OUTPUT); pinMode(SOL_LPWM, OUTPUT);
  pinMode(SAG_RPWM, OUTPUT); pinMode(SAG_LPWM, OUTPUT);
  ledcAttachChannel(SERVO_PIN, 50, 14, 7);   // hazir kalip: servo icin 50 Hz sinyal kurulumu
  servoAci(90.0f);                           // orta konumdan basla
}
void robotEnd() {
  surMotor(SOL_RPWM, SOL_LPWM, 0); surMotor(SAG_RPWM, SAG_LPWM, 0);
}
void teleopInit() {}
void teleopLoop() {
  auto js = probot::io::joystick_api::makeDefault();
  float ileri = js.getLeftY();
  float donus = js.getRightX();
  surMotor(SOL_RPWM, SOL_LPWM, ileri + donus);
  surMotor(SAG_RPWM, SAG_LPWM, ileri - donus);

  if (js.getA())      servoAci(20.0f);    // A: parmaklari kapat
  else if (js.getB()) servoAci(110.0f);   // B: parmaklari ac

  delay(20);
}
void autonomousInit() {}
void autonomousLoop() { delay(20); }
🎬 VİDEO · ekran-kaydi · 3 dk · Kodu yapıştır, kart ve portu seç, yükle; telefonla robotun ağına bağlan, Driver Station'dan Init ve Start ile başla; A'ya basınca parmaklar kapanır, B'ye basınca açılır; sonra servoAci(20.0f) içindeki 20 değeri değiştirilip yeniden yüklenir

Yüklemeden önce bir tahmin yürüt: A'ya bir kez basıp bıraktığında parmaklar kapanacak. Sonra elini butondan çektiğinde ne olur, geri açılır mı, kapalı mı kalır? Tahminini bir kenara yaz.

Bağlan ve dene. Telefonu robotun açtığı RobotAdi ağına bağla. Tarayıcıya http://192.168.4.1 yaz (https değil). Driver Station açılınca kumandayı telefona bağla ve bir tuşuna bas; tarayıcı kumandayı ancak bir tuşa basınca tanır. Sonra Init'e, ardından Start'a bas.

Şimdi A'ya bas: parmaklar kapanır. B'ye bas: açılır. Bir de tahminini sına; A'ya basıp elini çektiğinde parmaklar kapalı kalır, çünkü servo son söylenen açıda durur ve orayı korur. Sürüş çubuklarını da dene; gripper açıp kapanırken robot yine sürülüyor. İkisi aynı anda çalışıyor.

Bir şeyi daha gözle ve kulağını ver: parmaklar kapandıktan sonra servodan çok hafif bir uğultu gelebilir. Bu, servonun konumunu koruma sesidir. Cismi elinle hafifçe itmeye çalış; servo geri direnir. DC motorun asla yapamayacağı şey bu.

Servo neden farklı (7 dk)

Gripper çalıştı. Şimdi olan bitenin adını koyalım.

Robotu süren motorlar DC motor. Onlara "dön" dersin, dönerler; "dur" dersin, dururlar. Ama nerede durduklarını bilmezler. Gripper'daki parça ise servo motor. Servoya bir derece söylersin, o dereceye gider ve komut değişene kadar orada durup o açıyı korur. "Yarıya kadar kapan ve orada kal" diyebildiğin motor budur.

Kodda bunu üç yerde görüyorsun:

Kancadaki sorunun cevabı buydu: servoya sürekli komut yağdırmıyorsun. A'ya bastığın anda bir kez "20 dereceye git" dersin; servo oraya gider ve sen başka bir şey söyleyene kadar orada kalır. Butonu bıraksan da açı değişmez.

Kalibrasyon: doğru açıları bul (15 dk)

Koddaki 20 ve 110 değerleri bir tahminden ibaret. Senin gripper'ın tam kapanması için belki 15 derece gerekir, belki 30. Bunu hesapla bulamazsın; kalibrasyon yaparak, yani deneyerek bulursun. Robotu yakından izleyerek ve servoyu dinleyerek çalış.

Önce kapanma açısını ayarla. if (js.getA()) servoAci(20.0f); satırındaki 20.0f değerini değiştir, yükle, A'ya bas, gözle:

  1. Değeri biraz düşür, örneğin 15.0f. Parmaklar daha çok kapanır. Bir cisim koy; iyice kavrıyor mu?
  2. Daha da düşür, 5.0f dene. Burada dikkat: parmaklar birbirine ya da gövdeye dayandığında servo daha ileri gitmeye çalışıp gidemez. O an servodan zorlanma sesi gelir, uzun bir uğultu duyarsın. Bu sesi duyduğun an dur. Servo, gidemeyeceği bir yere itiliyor demektir; bu ısınmasına ve yıpranmasına yol açar.
  3. Sesi duyduğun değerden geri çek. Servo rahatça, ses çıkarmadan durabildiği en kapalı açıyı bul. Cismi tutan ama servoyu zorlamayan değer, senin doğru kapanma açındır.

Şimdi açılma açısını ayarla. servoAci(110.0f) içindeki 110.0f ile aynı şeyi yap. Parmakların cismi rahatça bırakacak kadar açıldığı, ama gripper'ın mekaniğini uçta zorlamadığı değeri bul. Çok büyük bir açı da servoyu diğer uçta zorlar; yine kulağını ver.

Güvenlik kuralı:

Servo bir uçta zorlanıp uğuldarsa, o açıyı asla kodda bırakma. Zorlanan servo ısınır, dişlileri yıpranır ve zamanla bozulur. Kural basit: servoyu duyduğun yerde değil, rahat durduğu yerde bırak.

Kalibrasyon bitince kapanma ve açılma açıların hazır. Bunları bir kenara not et; sonraki derste, farklı nesneler için bu açıları tek tek yeniden ayarlayacaksın.

Ders sonu kontrolü (6 dk)

Kısa bir öz kontrol. Cevabını kendi cümlelerinle ver:

Günlük hayat bağı. Bir yazıcının kağıt tutucusu, bir kameranın açı motoru, oyuncak bir robot kolun eklemi... hepsi servo mantığıyla çalışır: bir konuma git ve orada dur. Kalibrasyon da mühendislikte her yerde var. Bir 3D yazıcı ilk çalıştırılırken, bir robot kol kurulurken uç noktaları hep denenerek ve dinlenerek ayarlanır. Bugün servoyu dinleyip geri çekmeyi öğrendin; bu, gerçek bir mühendisin refleksidir.

Erken bitirdiysen