2 / 6 tamamlandı
görev 2 · ~30 dk

Sayı doğru, anlamı yanlış

Mars Climate Orbiter, 1999 — kod sayıyı taşır, birimi taşımaz

hedef

Bir sayının yanında birimi yoksa ne olabileceğini görmek.

Ne oldu?

23 Eylül 1999. NASA'nın Mars Climate Orbiter sondası, dokuz aylık yolculuğun sonunda Mars'ın etrafında yörüngeye girmeye çalışıyor. Sonda insansız.

Yörüngeye girmesi gereken an geçiyor. Sondadan sinyal gelmiyor. Bir daha da hiç gelmedi.

Sonda Mars'a planlanandan çok daha alçaktan yaklaşmıştı. Muhtemelen atmosferde parçalandı.

Neden?

Sondayı iki farklı ekip yönetiyordu.

Bir libre-kuvvet yaklaşık 4,45 newton.

Yani motor her ateşlendiğinde gerçekte, rota hesabının sandığından dört buçuk kat fazla itiyordu. Tek bir ateşlemede fark küçüktü. Ama dokuz ay boyunca yapılan her küçük ateşlemede birikti.

Sayılar doğruydu. Kod hatasız çalışıyordu. Sadece iki ekip, aynı sayıya farklı anlam veriyordu.

Senin kartında

Sondanın motoru beş kez ateşleniyor. Birinci ekibin fonksiyonu itkiyi veriyor, ikinci ekip onu kullanıp hız değişimini planlıyor.

kod · .ino
const float KUTLE_KG = 600.0;   // ornek sonda kutlesi

// Birinci ekip yazdi: motorun verdigi itki
// (libre-kuvvet x saniye)
float motorItkisi() {
  return 10.0;
}

void setup() {
  Serial.begin(9600);

  float biriken = 0;

  for (int i = 1; i <= 5; i++) {
    float itki = motorItkisi();

    // Ikinci ekip: bu sayinin newton x saniye oldugunu varsayiyor
    float planlanan = itki / KUTLE_KG;

    // Fizik ne derse o: motor gercekte bu kadar itti
    float gercek = (itki * 4.448) / KUTLE_KG;

    biriken = biriken + (gercek - planlanan);

    Serial.print("atesleme ");
    Serial.print(i);
    Serial.print("  plan: ");
    Serial.print(planlanan, 4);
    Serial.print("  gercek: ");
    Serial.print(gercek, 4);
    Serial.print("  biriken fark: ");
    Serial.println(biriken, 4);
  }
}

void loop() {
}

gercek satırına dikkat et. O satır kodun değil, evrenin satırı. Motor ne kadar itiyorsa sonda o kadar hızlanır — yazılımın ne sandığı umurunda değil.

Çalıştı mı?

Serial Monitor'de beş satır görmelisin:

kod
atesleme 1  plan: 0.0167  gercek: 0.0741  biriken fark: 0.0575
atesleme 2  plan: 0.0167  gercek: 0.0741  biriken fark: 0.1149
...
atesleme 5  plan: 0.0167  gercek: 0.0741  biriken fark: 0.2873

Her ateşlemede plan ile gerçek arasında aynı küçük fark var. Ve fark birikiyor.

Beş ateşleme küçük görünüyor. Mars'a giden yolculuk dokuz ay sürdü.

Şimdi sen yaz

İki adımda düzelteceksin.

1. Dönüştür. Libre-kuvveti newtona çeviren bir fonksiyon yaz, sonra planlanan hesabında onu kullan.

kod · .ino
float lbfToN(float lbf) {
  // ŞİMDİ SEN YAZ:
  // 1 libre-kuvvet = 4.448 newton
}

2. Birimi adına yaz. motorItkisi fonksiyonunun adını motorItkisi_lbfs yap. Değişkenleri de öyle: itki_lbfs, itki_Ns.

🔍 İpucu 1

Fonksiyon gelen sayıyı 4.448 ile çarpıp geri vermeli. return kullan — Kodun dili Görev 8.

Sonra planlanan satırında itki yerine lbfToN(itki) yaz.

✅ Cevap
kod · .ino
float lbfToN(float lbf) {
  return lbf * 4.448;
}

Ve planlanan satırı:

kod · .ino
    float planlanan = lbfToN(itki) / KUTLE_KG;

Şimdi biriken fark her satırda 0.0000 olmalı.

İkinci adım daha önemli. Dönüşümü bir kez düzeltmek kolay. Ama altı ay sonra biri yeni bir fonksiyon yazıp motorItkisi()'nin sonucunu yine newton sanarsa? Birimi adın içine yazarsan bu hata yapılamaz hale gelir:

kod · .ino
float itki_lbfs = motorItkisi_lbfs();
float itki_Ns   = lbfToN(itki_lbfs);
float planlanan = itki_Ns / KUTLE_KG;

itki_lbfs / KUTLE_KG yazmak artık göze batar. Yanlış kodu yazmak zorlaşır. Mühendislikte bu, hatayı düzeltmekten daha değerli: hatayı yapılamaz hale getirmek.

📄 Görevin tam kodu
kod · .ino
const float KUTLE_KG = 600.0;

float motorItkisi_lbfs() {
  return 10.0;
}

float lbfToN(float lbf) {
  return lbf * 4.448;
}

void setup() {
  Serial.begin(9600);

  float biriken = 0;

  for (int i = 1; i <= 5; i++) {
    float itki_lbfs = motorItkisi_lbfs();
    float itki_Ns   = lbfToN(itki_lbfs);

    float planlanan = itki_Ns / KUTLE_KG;
    float gercek    = (itki_lbfs * 4.448) / KUTLE_KG;

    biriken = biriken + (gercek - planlanan);

    Serial.print("atesleme ");
    Serial.print(i);
    Serial.print("  plan: ");
    Serial.print(planlanan, 4);
    Serial.print("  gercek: ");
    Serial.print(gercek, 4);
    Serial.print("  biriken fark: ");
    Serial.println(biriken, 4);
  }
}

void loop() {
}

Olmadıysa

Ne görüyorsun Ne yap
Sayılar 0.02 gibi kısa Serial.print(planlanan, 4) — virgülden sonraki 4 basamak sayısı, unutma
Biriken fark düzeltmeden sonra da sıfır değil planlanan satırında lbfToN(itki) kullanmayı unutmuşsun
lbfToN was not declared Fonksiyonu setup'ın dışına, üstüne yaz
Biriken fark -0.0000 Normal. Ondalık sayılarda çok küçük yuvarlama farkları olur, sıfır demek

Kendini test et

Soru: Sayılar doğruydu, iki ekibin kodu da hatasız çalıştı. Hata tam olarak neredeydi?

Cevabı gör

İki ekibin arasında.

Kod bir sayıyı bir yerden öbür yere taşıdı. Ama sayının ne anlama geldiğini taşımadı. "10" yazan bir değişken, kendi kendine 10 libre mi 10 newton mu olduğunu söylemez.

Soruşturmada ortaya çıktı ki iki ekip arasındaki anlaşma belgesi newton kullanılmasını zaten istiyordu. Ama belge koda girmemişti. Yolculuk sırasında bazı mühendisler rotanın beklenenden farklı olduğunu fark etti — sebebi bulunamadı.

Bu yüzden iyi mühendisler birimi değişkenin adına yazar. Belge unutulabilir; değişkenin adı her satırda gözünün önündedir.

Bu hata nerede karşına çıkar

Akıllı Sera kitinin ilk görevinin bütün konusu bu: toprak sensörü sana "%40 nemli" demez, sadece bir sayı verir. O sayıya anlamı sensör vermez, sen verirsin. Kalibrasyon dediğimiz şey, bir sayıya doğru anlamı vermenin adı.


Takıldın, hata tablosu da yetmedi mi?

WhatsApp'tan sor — hangi görevdesin, ekranda ne yazıyor, devrenin fotoğrafı.