Okullar için Robotik ve Mühendislik · anaokulundan liseye

3. ünite / 10 · yaklaşık 4 saat

Pi üzerinde Python: betikten bakımı kolay programa

Sanal ortam, modüller, dataclass, dosyaya günlük yazma, pytest ve NumPy ile ölçüm analizi.

Bu ünitenin sonunda

  • Python betiğini terminalden çalıştırmak ve sanal ortamla bağımlılıkları yönetmek
  • Donanım okuyan kodu saf mantıktan ayırıp testlenebilir yazmak
  • Ölçümleri CSV'ye güvenli biçimde günlüklemek
  • NumPy ile motor ölçümlerinden doğru uydurmak ve ileri besleme değeri çıkarmak

Ders notları

Pi'de Python iki iş için kullanılır: donanımla konuşmak (gpiozero, picamera2, smbus2) ve veriyle düşünmek (NumPy, OpenCV). İkisini aynı fonksiyonda karıştırmak, kodu hem test edilemez hem de Pi dışında çalışamaz yapar.

Proje düzeni

  • robot/hw.py: donanım sınıfları (motor, sensör). Yalnız burada gpiozero içe aktarılır.
  • robot/logic.py: saf fonksiyonlar (özetleme, denetim, karar). Dizüstünde de çalışır.
  • tests/: pytest testleri; donanım yerine sahte (fake) nesneler.
  • main.py: ikisini birbirine bağlar.

Sanal ortam

Raspberry Pi OS Bookworm, sistem Python'una pip ile kurmayı engeller (PEP 668). python3 -m venv --system-site-packages .venv hem apt ile gelen picamera2 ve gpiozero'yu görür hem de pip paketlerini projeye özel tutar. requirements.txt sürümleri sabitler.

Günlük ve analiz

Robot sahada çalışırken ne olduğunu ancak günlükten öğrenirsin. Her satıra zaman damgası koy, flush() ile diske yaz. Sonra veriyi NumPy ile incele: aşağıdaki örnek Pi'de toplanmış 40 motor ölçümüne doğru uydurur, ölü bölgeyi ve 20 cm/s için gereken PWM'i bulur. Bu sayı, 7. ünitede PI denetimine ileri besleme olarak girecek.

Simülasyon

Raspberry Pi OS terminali (benzetim)

Küçük bir sanal dosya sistemi üzerinde gerçek komutlar: ls, cd, cat, nano, chmod, sudo, apt, systemctl, journalctl, i2cdetect. Ağ, paket kurulumu ve ssh benzetimdir; hiçbir şey indirilmez. Görev listesi durumu denetleyerek işaretlenir.

Raspberry Pi OS benzetimi. "help" yaz.

Görevler · 0/4

  • Python sürümünü öğren (python3 --version)
  • blink.py betiğini çalıştır
  • nano ile blink.py'deki bekleme süresini değiştir ve kaydet
  • Yeni bir hello.py yaz (print içeren) ve çalıştır

Hızlı komutlar (dokun, Enter'a bas):

Kendin dene

Aşağıdaki Python kodunu tarayıcıda çalıştır (Pyodide): ölü bölge ve 20 cm/s için PWM değerini not et. Kodu değiştirip 30 cm/s için hesapla. Terminalde python3 blink.py çalıştır, sonra nano ile blink.py'deki bekleme süresini değiştirip kaydet. Gerçek Pi'de: sanal ortam kur, pytest ile test_summarize'ı geçir.

Tarayıcıda Python

Kodu tarayıcıda çalıştırPython · NumPy · matplotlib · Pyodide

Python ve NumPy bu sayfada, tarayıcında çalışır (Pyodide). Kodu değiştirip yeniden çalıştırabilirsin; dersin veri setleri çalışma klasöründe hazır. Kod matplotlib kullanırsa grafikler çıktının altında görünür, yazdığı dosyalar (ör. egitim_gecmisi.csv) indirilebilir.

motor_fit.pypython

Çıktı

Çıktı burada görünecek.

Kod

Sensör günlüğü: dataclass, csv ve testlenebilir fonksiyon
from dataclasses import dataclass
from statistics import mean, pstdev
import csv, time

@dataclass
class Reading:
    t: float
    temp_c: float

def summarize(rows: list[Reading]) -> dict:
    """Saf fonksiyon: donanım yok, pytest ile test edilir"""
    temps = [r.temp_c for r in rows]
    return {"n": len(temps), "mean": round(mean(temps), 2), "std": round(pstdev(temps), 2), "max": max(temps)}

def log_forever(read_temp, path="logs/temp.csv", period=1.0):
    # read_temp dışarıdan verilir: testte sahte, Pi'de DS18B20 okuyucu
    with open(path, "a", newline="") as f:
        w = csv.writer(f)
        while True:
            w.writerow([time.time(), read_temp()])
            f.flush()          # elektrik kesilirse son satır kaybolmasın
            time.sleep(period)

def test_summarize():
    s = summarize([Reading(0, 20.0), Reading(1, 22.0)])
    assert s["mean"] == 21.0 and s["max"] == 22.0

Sık yapılan hatalar

  • sudo pip install: sistem Python'unu bozar; Bookworm zaten engeller. Sanal ortam kullan.
  • Donanım koduyla mantığı aynı fonksiyonda yazmak: test etmek için Pi gerekir.
  • Günlüğü flush etmeden tutmak: elektrik kesilince son dakikalar kaybolur.
  • Kayan noktalı sayıları == ile karşılaştırmak: testlerde round ya da pytest.approx kullan.

Yazılım mühendisliği bağlantısı

Bağımlılığı dışarıdan verme (dependency injection): log_forever(read_temp) sensörü parametre olarak alır.

  • Testte lambda: 21.5 verilir, Pi'de gerçek okuyucu.
  • Aynı fikir 10. ünitede ROS 2 düğümlerinde ve bitirme projesinin Drive sınıfında tekrar karşına çıkacak.

Kendini sına

  1. Bookworm'da pip paketleri için önerilen yol hangisidir?

  2. --system-site-packages seçeneği ne sağlar?

  3. Neden donanım okuma kodu saf mantıktan ayrılır?

  4. Motor ölçümüne uydurulan doğru hız = a·PWM + b ise ölü bölge nerededir?

Gerçek parçalar (Hyvex, 3B modelli)

Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç