<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-10-31T18:05:49+00:00</updated><id>https://program.sonsuz.us/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Beyin–Bilgisayar Arayüzleri: Düşünceden Komuta Giden Yol</title><link href="https://program.sonsuz.us/posts/beyinbilgisayar-arayuzleri-dusunceden-komuta-giden-yol/" rel="alternate" type="text/html" title="Beyin–Bilgisayar Arayüzleri: Düşünceden Komuta Giden Yol" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/beyinbilgisayar-arayuzleri-dusunceden-komuta-giden-yol</id><content type="html" xml:base="https://program.sonsuz.us/posts/beyinbilgisayar-arayuzleri-dusunceden-komuta-giden-yol/"><![CDATA[<p>Klavyeye dokunmadan bir imleci hareket ettirmek mümkün mü? Evet; ancak bilgisayar zihninizdeki bütün cümleleri okumuyor. Beyin–bilgisayar arayüzleri, belirli sinirsel etkinlik örüntülerini ölçüp sınırlı komutlara dönüştürüyor. Yani mesele telepati değil, gürültülü biyolojik sinyallerle çalışan dikkatli bir mühendislik projesi. Beyninizin gizli bir USB portu yok; keşke kurulum bu kadar kolay olsaydı!</p>

<p>``</p>

<h2 id="önce-beklentiyi-doğru-ayarlayalım">Önce beklentiyi doğru ayarlayalım</h2>

<p>Bir beyin–bilgisayar arayüzü, İngilizce kısaltmasıyla <strong>BCI</strong>, kas hareketlerini zorunlu tutmadan sinirsel etkinlik üzerinden iletişim kurmayı hedefler. Örneğin kullanıcı sağ veya sol elini hareket ettirdiğini hayal eder; sistem bu iki durumu ayırt etmeye çalışır. Bazı sistemlerdeyse kullanıcı yanıp sönen seçeneklerden birine odaklanır. Buradaki bilgi, serbest düşüncenin içeriği değil, önceden tanımlanmış bir görevle ilişkili örüntüdür.</p>

<p>Ölçüm yöntemleri aynı kapıya farklı yollardan ulaşır:</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Nasıl ölçer?</th>
      <th>Avantaj</th>
      <th>Temel sınırlama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>EEG</td>
      <td>Saçlı derideki elektrotlarla</td>
      <td>Ameliyat gerektirmez</td>
      <td>Gürültü ve düşük uzamsal çözünürlük</td>
    </tr>
    <tr>
      <td>ECoG</td>
      <td>Beyin yüzeyindeki elektrotlarla</td>
      <td>Daha yerel sinyaller</td>
      <td>Cerrahi işlem gerekir</td>
    </tr>
    <tr>
      <td>Beyin içi elektrotlar</td>
      <td>Sinir dokusu içinden</td>
      <td>Ayrıntılı kayıt potansiyeli</td>
      <td>Cerrahi risk ve uzun dönem kararlılık</td>
    </tr>
  </tbody>
</table>

<h2 id="sinyalden-komuta-küçük-bir-çeviri-fabrikası">Sinyalden komuta: küçük bir çeviri fabrikası</h2>

<p>Tipik işlem zinciri şöyledir:</p>

<p><strong>Ölçüm → temizleme → özellik çıkarımı → sınıflandırma → komut → geri bildirim.</strong></p>

<p>EEG, tek bir nöronun konuşması değildir. Çok sayıda kaynağın elektriksel etkileri, ölçüm noktasında birbirine karışır. Göz kırpması, çene kasları ve elektrik şebekesi de bu karışıma katılabilir. Dolayısıyla yüksek genlik, otomatik olarak güçlü bir niyet anlamına gelmez.</p>

<p>Motor imgelemede sık incelenen özellikler, yaklaşık <strong>8–13 Hz mu</strong> ve <strong>13–30 Hz beta</strong> bantlarındaki güç değişimleridir. Bu değişimler kişiye ve göreve göre farklılaşır; sabit bir düşünce sözlüğü oluşturmazlar. Özellik vektörünü $h$ ile gösterirsek, basit bir ikili sınıflandırıcı şöyle yazılabilir:</p>

\[z = w^T h + b\]

\[p = 1/(1 + e^{-z})\]

<p>Burada $w$ öğrenilen ağırlıkları, $b$ sabit terimi, $p$ ise modelin bir sınıfa verdiği olasılık tahminini temsil eder. Bu tahminin güvenilirliği ayrıca değerlendirilmelidir. Model, kişinin niyetini doğrudan bilmez; eğitim verisindeki ilişkilere dayanarak karar verir. <strong>Korelasyon, zihin okuma değildir.</strong></p>

<h2 id="python-ile-bant-gücünden-sınıflandırmaya">Python ile bant gücünden sınıflandırmaya</h2>

<p>Aşağıdaki örnek, NumPy, SciPy ve scikit-learn kullanır. Dosyada artefaktları önceden ele alınmış EEG denemeleri bulunmalıdır: <code class="language-plaintext highlighter-rouge">X</code> boyutu <code class="language-plaintext highlighter-rouge">(deneme, kanal, örnek)</code>, <code class="language-plaintext highlighter-rouge">y</code> sağ/sol imgeleme etiketleri, <code class="language-plaintext highlighter-rouge">oturum</code> kayıt oturumu kimlikleri, <code class="language-plaintext highlighter-rouge">fs</code> örnekleme frekansıdır. En az üç farklı oturum gerekir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">from</span> <span class="n">scipy.signal</span> <span class="kn">import</span> <span class="n">welch</span>
<span class="kn">from</span> <span class="n">sklearn.pipeline</span> <span class="kn">import</span> <span class="n">make_pipeline</span>
<span class="kn">from</span> <span class="n">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">StandardScaler</span>
<span class="kn">from</span> <span class="n">sklearn.linear_model</span> <span class="kn">import</span> <span class="n">LogisticRegression</span>
<span class="kn">from</span> <span class="n">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">GroupKFold</span><span class="p">,</span> <span class="n">cross_val_score</span>

<span class="n">d</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">load</span><span class="p">(</span><span class="sh">"</span><span class="s">eeg_denemeleri.npz</span><span class="sh">"</span><span class="p">)</span>
<span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">oturum</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">X</span><span class="sh">"</span><span class="p">],</span> <span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">y</span><span class="sh">"</span><span class="p">],</span> <span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">oturum</span><span class="sh">"</span><span class="p">]</span>
<span class="n">fs</span> <span class="o">=</span> <span class="nf">float</span><span class="p">(</span><span class="n">d</span><span class="p">[</span><span class="sh">"</span><span class="s">fs</span><span class="sh">"</span><span class="p">])</span>
<span class="n">f</span><span class="p">,</span> <span class="n">psd</span> <span class="o">=</span> <span class="nf">welch</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">fs</span><span class="o">=</span><span class="n">fs</span><span class="p">,</span>
               <span class="n">nperseg</span><span class="o">=</span><span class="nf">min</span><span class="p">(</span><span class="mi">256</span><span class="p">,</span> <span class="n">X</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>

<span class="n">bantlar</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">alt</span><span class="p">,</span> <span class="n">ust</span> <span class="ow">in</span> <span class="p">[(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">13</span><span class="p">),</span> <span class="p">(</span><span class="mi">13</span><span class="p">,</span> <span class="mi">30</span><span class="p">)]:</span>
    <span class="n">sec</span> <span class="o">=</span> <span class="p">(</span><span class="n">f</span> <span class="o">&gt;=</span> <span class="n">alt</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">f</span> <span class="o">&lt;</span> <span class="n">ust</span><span class="p">)</span>
    <span class="n">guc</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">trapezoid</span><span class="p">(</span><span class="n">psd</span><span class="p">[...,</span> <span class="n">sec</span><span class="p">],</span> <span class="n">f</span><span class="p">[</span><span class="n">sec</span><span class="p">],</span> <span class="n">axis</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">bantlar</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">guc</span> <span class="o">+</span> <span class="mf">1e-12</span><span class="p">))</span>
<span class="n">F</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">concatenate</span><span class="p">(</span><span class="n">bantlar</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>

<span class="n">model</span> <span class="o">=</span> <span class="nf">make_pipeline</span><span class="p">(</span><span class="nc">StandardScaler</span><span class="p">(),</span>
                      <span class="nc">LogisticRegression</span><span class="p">(</span><span class="n">max_iter</span><span class="o">=</span><span class="mi">1000</span><span class="p">))</span>
<span class="n">skorlar</span> <span class="o">=</span> <span class="nf">cross_val_score</span><span class="p">(</span>
    <span class="n">model</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">groups</span><span class="o">=</span><span class="n">oturum</span><span class="p">,</span>
    <span class="n">cv</span><span class="o">=</span><span class="nc">GroupKFold</span><span class="p">(</span><span class="n">n_splits</span><span class="o">=</span><span class="mi">3</span><span class="p">),</span> <span class="n">scoring</span><span class="o">=</span><span class="sh">"</span><span class="s">balanced_accuracy</span><span class="sh">"</span>
<span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">skorlar</span><span class="p">.</span><span class="nf">mean</span><span class="p">())</span>
</code></pre></div></div>

<p>Welch yöntemi güç spektrumunu tahmin eder; bant integralleri kanal başına özellik üretir. Logaritma, güç değerlerinin geniş aralığını sıkıştırır. Pipeline, ölçekleyicinin yalnızca eğitim bölümünde öğrenilmesini sağlar. Oturum bazlı bölme ise aynı kaydın benzer parçalarının eğitim ve teste karışmasını önler. Kod, NumPy 2 veya üzerindeki <code class="language-plaintext highlighter-rouge">trapezoid</code> işlevini kullanır.</p>

<h2 id="laboratuvardan-gerçek-hayata-geçiş">Laboratuvardan gerçek hayata geçiş</h2>

<p>Yüksek test başarısı, kullanışlı bir arayüz için tek başına yeterli değildir. Gecikme, yanlış komut sıklığı, kalibrasyon süresi ve kullanıcı yorgunluğu da ölçülmelidir. Dengeli doğruluk, sınıfların ayrı ayrı başarılarını eşit ağırlıkla değerlendirir. Rastgele deneme bölmek yerine yeni oturumlarda sınamak, günlük kullanım performansını anlamaya daha çok yardımcı olur.</p>

<p>Gerçek zamanlı sistemde kararsız tahminler komuta dönüştürülmeyebilir. Kullanıcıya geri bildirim vermek ve gerektiğinde onay istemek, özellikle tekerlekli sandalye gibi fiziksel sonuç doğuran uygulamalarda önemlidir. Bu örnek, güvenlik doğrulaması yapılmış bir kontrol sistemi değildir.</p>

<p>Sinirsel kayıtlar da hassas verilerdir: açık rıza, sınırlı saklama ve güvenli erişim tasarımın parçası olmalıdır. Klinik uygulamalarda profesyonel değerlendirme gerekir. Sonuç olarak düşünceden komuta geçmek mümkün; fakat başarılı BCI, sihirli bir okuyucu değil, kullanıcıyla birlikte öğrenen kontrollü bir çevirmen gibi çalışır.</p>

<p><img src="/img/beyinbilgisayar-arayuzleri-dusunceden-37.svg" alt="beyinbilgisayar-arayuzleri-dusunceden-37" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="beyin-bilgisayar-arayüzü" /><category term="eeg" /><category term="makine-öğrenmesi" /><category term="sinyal-işleme" /><category term="nöroteknoloji" /><category term="python" /><summary type="html"><![CDATA[Klavyeye dokunmadan bir imleci hareket ettirmek mümkün mü? Evet; ancak bilgisayar zihninizdeki bütün cümleleri okumuyor. Beyin–bilgisayar arayüzleri, belirli sinirsel etkinlik örüntülerini ölçüp sınırlı komutlara dönüştürüyor. Yani mesele telepati değil, gürültülü biyolojik sinyallerle çalışan dikkatli bir mühendislik projesi. Beyninizin gizli bir USB portu yok; keşke kurulum bu kadar kolay olsaydı!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/beyinbilgisayar-arayuzleri-dusunceden-37.png" /><media:content medium="image" url="https://program.sonsuz.us/img/beyinbilgisayar-arayuzleri-dusunceden-37.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bir Gövde, Birçok Görev: Modüler Robot Tasarımının Esnekliği</title><link href="https://program.sonsuz.us/posts/bir-govde-bircok-gorev-moduler-robot-tasariminin-esnekligi/" rel="alternate" type="text/html" title="Bir Gövde, Birçok Görev: Modüler Robot Tasarımının Esnekliği" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bir-govde-bircok-gorev-moduler-robot-tasariminin-esnekligi</id><content type="html" xml:base="https://program.sonsuz.us/posts/bir-govde-bircok-gorev-moduler-robot-tasariminin-esnekligi/"><![CDATA[<p><img src="/img/bir-govde-bircok-15.svg" alt="bir-govde-bircok-15" /></p>

<p>Bir robotun sabah depoda kutu taşıyıp öğleden sonra serada bitki kontrolü yaptığını düşünün. Bunu iki ayrı makineyle çözmek mümkün; ancak modüler tasarım, aynı gövdenin hareket, algılama ve tutma bileşenlerini değiştirerek farklı görevlere uyarlanmasını sağlar. Robot biraz LEGO setine benzer, fakat burada parçaların yalnızca birbirine oturması değil, birlikte güvenle çalışması gerekir.
``</p>

<h2 id="modülerlik-parçalardan-daha-büyük-bir-fikir">Modülerlik: Parçalardan Daha Büyük Bir Fikir</h2>

<p>Modüler robot, belirli işlevleri bağımsız birimlere ayıran robot mimarisidir. Tekerlek takımı hareketi, kamera çevreyi algılamayı, kavrayıcı ise nesnelerle etkileşimi üstlenebilir. Her birimin görev sınırı ve bağlantı kuralları açıkça tanımlanır. Böylece bir bileşeni değiştirmek, robotun tamamını yeniden tasarlamayı gerektirmez. Buradaki temel ilke, <strong>işlevsel ayrıştırma ve standart arayüzlerdir</strong>.</p>

<p>Bu yaklaşımın iki yaygın biçimi vardır. Sabit gövdeli sistemlerde uç araçlar ve sensörler değiştirilir. Yeniden yapılandırılabilir sistemlerde ise bağlantılı modüller robotun fiziksel biçimini de değiştirebilir. İlk yaklaşım endüstriyel uygulamalarda daha kolay yönetilirken ikincisi daha geniş hareket olanakları sunar; buna karşılık kontrol ve bağlantı tasarımı zorlaşır.</p>

<p>Mimariyi $G=(V,E)$ grafiğiyle düşünebiliriz: $V$ modülleri, $E$ ise aralarındaki bağlantıları temsil eder. Bağlantının mekanik, elektriksel veya veri taşıyan niteliği önemlidir. Bir kameranın takılabilmesi, kontrol yazılımının onu kullanabileceği anlamına gelmez!</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Sabit tasarım</th>
      <th>Modüler tasarım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Görev değişimi</td>
      <td>Yeni tasarım gerekebilir</td>
      <td>Uygun parça değiştirilebilir</td>
    </tr>
    <tr>
      <td>Bakım</td>
      <td>Bütün sisteme müdahale gerekebilir</td>
      <td>Arızalı birim ayrılabilir</td>
    </tr>
    <tr>
      <td>Optimizasyon</td>
      <td>Tek görevde yüksek olabilir</td>
      <td>Arayüzlerden kaynaklanan ödünleşimler vardır</td>
    </tr>
    <tr>
      <td>Başlangıç geliştirmesi</td>
      <td>Daha sade olabilir</td>
      <td>Standartlaştırma yatırımı ister</td>
    </tr>
  </tbody>
</table>

<h2 id="esnekliğin-gizli-kahramanı-arayüzler">Esnekliğin Gizli Kahramanı: Arayüzler</h2>

<p>Başarılı modülerlik, bağlantı noktasında başlar. Mekanik arayüz; ölçüleri, kilitleme yöntemini ve taşınabilecek yükü belirlemelidir. Elektriksel arayüz; gerilim, akım sınırı, kutuplama ve koruma düzenini tanımlar. Veri arayüzü ise mesaj biçimini, haberleşme hızını ve hata davranışını kapsar. CAN veya Ethernet kullanmak tek başına yeterli değildir; modüllerin aynı mesajların anlamında da anlaşması gerekir.</p>

<p>Yazılım tarafında sürücüler, donanım ayrıntılarını ortak yeteneklere dönüştürebilir. Örneğin farklı kavrayıcılar aynı “aç”, “kapat” ve “durum oku” işlemlerini sunar. Böylece görev planlayıcısı marka veya model yerine yeteneklerle çalışır. Yine de kavrama kuvveti ve konum hassasiyeti gibi sınırlar ayrıca bildirilmelidir.</p>

<p>Fizik kuralları ise tak-çıkar heyecanına kapılmaz. Bir kolun yükten kaynaklanan torku basitçe $T=F r$ ile hesaplanır. Burada $F$ kuvvet, $r$ dönme eksenine olan dik uzaklıktır. Aynı yükü iki kat uzağa taşımak, tork ihtiyacını iki katına çıkarır. Dolayısıyla daha uzun modül, daha güçlü motor veya daha düşük taşıma kapasitesi gerektirebilir.</p>

<h2 id="python-ile-göreve-uygun-yapılandırma">Python ile Göreve Uygun Yapılandırma</h2>

<p>Aşağıdaki örnek, seçilen modüllerin besleme gerilimini ve görev yeteneklerini denetler. Donanımı hareket ettirmez; yapılandırmanın yazılım düzeyindeki bir ön kontrolüdür. Python 3.9 ve üzeriyle çalışır.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>

<span class="nd">@dataclass</span><span class="p">(</span><span class="n">frozen</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Module</span><span class="p">:</span>
    <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
    <span class="n">capabilities</span><span class="p">:</span> <span class="nb">frozenset</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
    <span class="n">voltage</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">24</span>

<span class="n">modules</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">"</span><span class="s">drive</span><span class="sh">"</span><span class="p">:</span> <span class="nc">Module</span><span class="p">(</span><span class="sh">"</span><span class="s">Tekerlek</span><span class="sh">"</span><span class="p">,</span> <span class="nf">frozenset</span><span class="p">({</span><span class="sh">"</span><span class="s">hareket</span><span class="sh">"</span><span class="p">})),</span>
    <span class="sh">"</span><span class="s">gripper</span><span class="sh">"</span><span class="p">:</span> <span class="nc">Module</span><span class="p">(</span><span class="sh">"</span><span class="s">Kavrayıcı</span><span class="sh">"</span><span class="p">,</span> <span class="nf">frozenset</span><span class="p">({</span><span class="sh">"</span><span class="s">kavrama</span><span class="sh">"</span><span class="p">})),</span>
    <span class="sh">"</span><span class="s">camera</span><span class="sh">"</span><span class="p">:</span> <span class="nc">Module</span><span class="p">(</span><span class="sh">"</span><span class="s">Kamera</span><span class="sh">"</span><span class="p">,</span> <span class="nf">frozenset</span><span class="p">({</span><span class="sh">"</span><span class="s">görüntüleme</span><span class="sh">"</span><span class="p">})),</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">configure</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="n">required</span><span class="p">):</span>
    <span class="n">selected</span> <span class="o">=</span> <span class="p">[</span><span class="n">modules</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">names</span><span class="p">]</span>
    <span class="k">if</span> <span class="nf">any</span><span class="p">(</span><span class="n">module</span><span class="p">.</span><span class="n">voltage</span> <span class="o">!=</span> <span class="mi">24</span> <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">selected</span><span class="p">):</span>
        <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">Besleme gerilimi uyumsuz</span><span class="sh">"</span><span class="p">)</span>
    <span class="n">available</span> <span class="o">=</span> <span class="nf">frozenset</span><span class="p">().</span><span class="nf">union</span><span class="p">(</span>
        <span class="o">*</span><span class="p">(</span><span class="n">module</span><span class="p">.</span><span class="n">capabilities</span> <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">selected</span><span class="p">)</span>
    <span class="p">)</span>
    <span class="n">missing</span> <span class="o">=</span> <span class="nf">set</span><span class="p">(</span><span class="n">required</span><span class="p">)</span> <span class="o">-</span> <span class="n">available</span>
    <span class="k">if</span> <span class="n">missing</span><span class="p">:</span>
        <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">Eksik yetenekler: </span><span class="si">{</span><span class="nf">sorted</span><span class="p">(</span><span class="n">missing</span><span class="p">)</span><span class="si">}</span><span class="sh">"</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">module</span><span class="p">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">selected</span><span class="p">]</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">configure</span><span class="p">([</span><span class="sh">"</span><span class="s">drive</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">gripper</span><span class="sh">"</span><span class="p">],</span> <span class="p">{</span><span class="sh">"</span><span class="s">hareket</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">kavrama</span><span class="sh">"</span><span class="p">}))</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">configure</span><span class="p">([</span><span class="sh">"</span><span class="s">drive</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">camera</span><span class="sh">"</span><span class="p">],</span> <span class="p">{</span><span class="sh">"</span><span class="s">hareket</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">görüntüleme</span><span class="sh">"</span><span class="p">}))</span>
</code></pre></div></div>

<p>İlk çağrı taşıma, ikinci çağrı gözlem görevine uygun parçaları seçer. Gerçek uygulamada bu kontrole mekanik uyumluluk, akım bütçesi, haberleşme protokolü ve güvenlik kısıtları da eklenmelidir. Yetenek etiketi, performans garantisi değildir.</p>

<h2 id="parça-değiştiğinde-ne-yeniden-kontrol-edilmeli">Parça Değiştiğinde Ne Yeniden Kontrol Edilmeli?</h2>

<p>Modül değişimi sonrasında robotun kütlesi, ağırlık merkezi ve durma mesafesi değişebilir. Kamera değişirse kalibrasyon; kavrayıcı değişirse kuvvet sınırları ve araç koordinat sistemi güncellenmelidir. Yapılandırma kaydı tutmak, hangi donanımın hangi yazılım sürümüyle test edildiğini izlemeyi kolaylaştırır. Bu kayıtlar bakım ekibinin “Dün çalışıyordu!” bilmecesini çözmesinde özellikle değerlidir.</p>

<p>Sistem özel olarak enerjiliyken değişime uygun tasarlanmamışsa parçalar güç kesilerek değiştirilmelidir. Ardından bağlantılar doğrulanmalı, düşük hızda işlev testi yapılmalı ve güvenlik sınırları yeniden değerlendirilmelidir.</p>

<p>Modülerlik her durumda daha ucuz veya daha hafif değildir. Ek bağlantılar maliyet, boşluk ve arıza noktası yaratabilir. Ancak görevler sık değişiyorsa ortak gövdeyi korumak ciddi avantaj sağlar. İyi tasarlanmış modüler robot, her işi kusursuz yapan sihirli makine değil; yeni işleri kontrollü biçimde öğrenebilen bir mühendislik platformudur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="modüler tasarım" /><category term="mekatronik" /><category term="python" /><category term="otomasyon" /><summary type="html"><![CDATA[Bir robotun sabah depoda kutu taşıyıp öğleden sonra serada bitki kontrolü yaptığını düşünün. Bunu iki ayrı makineyle çözmek mümkün; ancak modüler tasarım, aynı gövdenin hareket, algılama ve tutma bileşenlerini değiştirerek farklı görevlere uyarlanmasını sağlar. Robot biraz LEGO setine benzer, fakat burada parçaların yalnızca birbirine oturması değil, birlikte güvenle çalışması gerekir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bir-govde-bircok-15.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bir-govde-bircok-15.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bir Sensörle Başlayan Zincir: Ev Otomasyonunda Olay Tabanlı Programlama</title><link href="https://program.sonsuz.us/posts/bir-sensorle-baslayan-zincir-ev-otomasyonunda-olay-tabanli-programlama/" rel="alternate" type="text/html" title="Bir Sensörle Başlayan Zincir: Ev Otomasyonunda Olay Tabanlı Programlama" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bir-sensorle-baslayan-zincir-ev-otomasyonunda-olay-tabanli-programlama</id><content type="html" xml:base="https://program.sonsuz.us/posts/bir-sensorle-baslayan-zincir-ev-otomasyonunda-olay-tabanli-programlama/"><![CDATA[<p>Gece koridora çıktığınızda lamba yanıyor, ardından telefonunuza aydınlatmanın açıldığı bilgisi geliyor. Siz yalnızca yürüdünüz; eviniz ise küçük bir yazılım orkestrası gibi çalıştı. Bu davranışın arkasında, cihazları sürekli sorgulamak yerine değişikliklere tepki veren olay tabanlı programlama bulunur. Gelin, tek bir sensör sinyalinin nasıl kontrollü bir otomasyon zincirine dönüştüğünü keşfedelim.</p>

<p>``</p>

<h2 id="olay-nedir-komuttan-farkı-ne">Olay nedir, komuttan farkı ne?</h2>

<p><strong>Olay</strong>, gerçekleşmiş bir durumun kaydıdır: “Hareket algılandı.” <strong>Komut</strong> ise yapılması istenen iştir: “Lambayı aç.” Bu ayrım önemlidir; hareket sensörü lambanın nasıl çalıştığını bilmek zorunda değildir. Yalnızca gözlemini yayınlar, otomasyon kuralları da uygun komutları üretir.</p>

<p>Tipik mimaride üç rol vardır: olayı üreten sensör, mesajı taşıyan olay veri yolu ve mesajı işleyen tüketiciler. MQTT kullanılan sistemlerde aracı sunucu mesajları abonelere iletir. Bununla birlikte, MQTT tek başına otomasyon kurallarını değerlendirmez; bu görev uygulamanıza veya otomasyon platformuna aittir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Çalışma biçimi</th>
      <th>Temel özellik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Periyodik sorgulama</td>
      <td>Sensöre düzenli aralıklarla sorar</td>
      <td>Tepki süresi sorgulama aralığına bağlıdır</td>
    </tr>
    <tr>
      <td>Olay tabanlı model</td>
      <td>Sensör değişikliği bildirir</td>
      <td>Gereksiz sorgulamayı azaltabilir</td>
    </tr>
    <tr>
      <td>Zamanlanmış görev</td>
      <td>Belirlenen saatte çalışır</td>
      <td>Sensör değişimi gerektirmez</td>
    </tr>
  </tbody>
</table>

<p>Bu yöntemler rakip değil, takım arkadaşıdır. Örneğin hareket olayı lambayı açarken, zamanlanmış bir görev gecenin sonunda açık kalan lambaları kapatabilir.</p>

<h2 id="zincirin-matematiği-olay-koşul-ve-durum">Zincirin matematiği: olay, koşul ve durum</h2>

<p>Bir kuralı “olay geldi, koşul doğruysa eylemi gerçekleştir” şeklinde düşünebiliriz. Hareketi $H$, gece koşulunu $G$, lambayı açma kararını $L$ ile gösterirsek:</p>

\[L = H \land G\]

<p>Ancak yalnızca koşulları değerlendirmek yetmez. Lambanın mevcut durumunu da bilmeliyiz. Durum geçişini $S_{t+1} = f(S_t, E_t)$ olarak yazabiliriz: yeni durum, önceki durum ve gelen olay tarafından belirlenir.</p>

<p>Lamba zaten açıksa tekrar açma komutu göndermemek, gereksiz işlemleri azaltır. Üstelik zincirin bir sonraki halkasını yalnızca gerçek durum değiştiğinde tetiklememizi sağlar. Böylece eviniz, aynı düğmeye heyecanla yüz kere basan bir robot gibi davranmaz.</p>

<h2 id="python-ile-küçük-bir-olay-zinciri">Python ile küçük bir olay zinciri</h2>

<p>Aşağıdaki örnek, sensör olayını bir kuyruğa bırakır. Hareket işleyicisi gece koşulunu değerlendirir; lamba açıldığında yeni bir olay üretir. İkinci işleyici de telefon bildirimini temsil eden çıktıyı oluşturur. Gerçek cihaz bağlantıları yerine simülasyon kullanıyoruz.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">asyncio</span>
<span class="kn">from</span> <span class="n">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>

<span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">Event</span><span class="p">:</span>
    <span class="n">kind</span><span class="p">:</span> <span class="nb">str</span>
    <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span>

<span class="n">bus</span> <span class="o">=</span> <span class="n">asyncio</span><span class="p">.</span><span class="nc">Queue</span><span class="p">()</span>
<span class="n">state</span> <span class="o">=</span> <span class="p">{</span><span class="sh">"</span><span class="s">light</span><span class="sh">"</span><span class="p">:</span> <span class="bp">False</span><span class="p">}</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">on_motion</span><span class="p">(</span><span class="n">event</span><span class="p">):</span>
    <span class="n">hour</span> <span class="o">=</span> <span class="n">event</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="sh">"</span><span class="s">hour</span><span class="sh">"</span><span class="p">]</span>
    <span class="n">is_night</span> <span class="o">=</span> <span class="n">hour</span> <span class="o">&gt;=</span> <span class="mi">22</span> <span class="ow">or</span> <span class="n">hour</span> <span class="o">&lt;</span> <span class="mi">6</span>
    <span class="k">if</span> <span class="n">is_night</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">state</span><span class="p">[</span><span class="sh">"</span><span class="s">light</span><span class="sh">"</span><span class="p">]:</span>
        <span class="n">state</span><span class="p">[</span><span class="sh">"</span><span class="s">light</span><span class="sh">"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">True</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Koridor lambası açıldı.</span><span class="sh">"</span><span class="p">)</span>
        <span class="k">await</span> <span class="n">bus</span><span class="p">.</span><span class="nf">put</span><span class="p">(</span><span class="nc">Event</span><span class="p">(</span><span class="sh">"</span><span class="s">light.changed</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">on</span><span class="sh">"</span><span class="p">:</span> <span class="bp">True</span><span class="p">}))</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">on_light</span><span class="p">(</span><span class="n">event</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">event</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="sh">"</span><span class="s">on</span><span class="sh">"</span><span class="p">]:</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Telefon bildirimi: Koridor aydınlatıldı.</span><span class="sh">"</span><span class="p">)</span>

<span class="n">handlers</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">"</span><span class="s">motion.detected</span><span class="sh">"</span><span class="p">:</span> <span class="n">on_motion</span><span class="p">,</span>
    <span class="sh">"</span><span class="s">light.changed</span><span class="sh">"</span><span class="p">:</span> <span class="n">on_light</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="k">await</span> <span class="n">bus</span><span class="p">.</span><span class="nf">put</span><span class="p">(</span><span class="nc">Event</span><span class="p">(</span><span class="sh">"</span><span class="s">motion.detected</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">hour</span><span class="sh">"</span><span class="p">:</span> <span class="mi">23</span><span class="p">}))</span>
    <span class="k">while</span> <span class="ow">not</span> <span class="n">bus</span><span class="p">.</span><span class="nf">empty</span><span class="p">():</span>
        <span class="n">event</span> <span class="o">=</span> <span class="k">await</span> <span class="n">bus</span><span class="p">.</span><span class="nf">get</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">handler</span> <span class="o">=</span> <span class="n">handlers</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">kind</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">handler</span><span class="p">:</span>
                <span class="k">await</span> <span class="nf">handler</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">bus</span><span class="p">.</span><span class="nf">task_done</span><span class="p">()</span>

<span class="n">asyncio</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span><span class="nf">main</span><span class="p">())</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">handlers</code> sözlüğü, olay türlerini ilgili fonksiyonlarla eşleştirir. Kuyruk ise üretici ile tüketiciyi birbirinden ayırır. Bu örnekte işleyiciler sırayla beklenir; <code class="language-plaintext highlighter-rouge">async</code> kullanılması bütün işlemlerin otomatik olarak paralel çalıştığı anlamına gelmez. Ayrıca döngü kuyruk boşalınca biter; sürekli çalışan uygulamada yeni olaylar <code class="language-plaintext highlighter-rouge">await bus.get()</code> ile beklenir.</p>

<p>Gerçek lambada durum değişikliğini, komut gönderildiği anda değil cihazdan doğrulama geldiğinde yayınlamak daha güvenilirdir. Aksi hâlde bağlantısı kopmuş bir lambayı yazılımda açık sanabilirsiniz.</p>

<h2 id="zinciri-güvenilir-tutmak">Zinciri güvenilir tutmak</h2>

<p>Olay tabanlı sistemlerin eğlenceli tarafı bağlantı kurmaktır; zor tarafı ise bağlantıları kontrol altında tutmaktır.</p>

<ul>
  <li><strong>Tekrarlanan mesajlar:</strong> Olay kimliği ve idempotent işleyiciler kullanın. Aynı olayın yeniden gelmesi sonucu değiştirmemelidir.</li>
  <li><strong>Sonsuz döngüler:</strong> Lambanın değişimi sensör kuralını yeniden tetikliyorsa döngü oluşabilir. Kaynak bilgisi ve açık geçiş kuralları ekleyin.</li>
  <li><strong>Sensör titreşimi:</strong> Çok kısa aralıklarla gelen sinyalleri filtrelemek için debounce uygulayın. Hareketli bir perdeyi misafir sanmayın!</li>
  <li><strong>Bağlantı kesintileri:</strong> Yeniden deneme, zaman aşımı ve durum uzlaştırma mekanizmaları tasarlayın. Tek bir mesajı mutlak gerçek kabul etmeyin.</li>
  <li><strong>Güvenlik:</strong> MQTT erişimini kimlik doğrulama ve konu bazlı yetkilerle sınırlandırın; kritik cihazlarda manuel kontrolü koruyun.</li>
</ul>

<p>Sonuç olarak iyi otomasyon, yalnızca cihazları bağlamak değildir. Olayın anlamını, koşullarını ve oluşturduğu durum değişikliklerini açıkça tanımlamaktır. Bu temel sağlam olduğunda, tek bir sensör evinizin geri kalanıyla düzenli ve anlaşılır bir sohbet başlatabilir.</p>

<p><img src="/img/bir-sensorle-baslayan-18.svg" alt="bir-sensorle-baslayan-18" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ev otomasyonu" /><category term="olay tabanlı programlama" /><category term="python" /><category term="sensörler" /><category term="asenkron programlama" /><category term="mqtt" /><summary type="html"><![CDATA[Gece koridora çıktığınızda lamba yanıyor, ardından telefonunuza aydınlatmanın açıldığı bilgisi geliyor. Siz yalnızca yürüdünüz; eviniz ise küçük bir yazılım orkestrası gibi çalıştı. Bu davranışın arkasında, cihazları sürekli sorgulamak yerine değişikliklere tepki veren olay tabanlı programlama bulunur. Gelin, tek bir sensör sinyalinin nasıl kontrollü bir otomasyon zincirine dönüştüğünü keşfedelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bir-sensorle-baslayan-18.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bir-sensorle-baslayan-18.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Sınıflar, Nesneler ve Metotlar: ref ve out ile Nesne Modelini Anlamak</title><link href="https://program.sonsuz.us/posts/c-siniflar-nesneler-ve-metotlar-ref-ve-out-ile-nesne-modelini-anlamak/" rel="alternate" type="text/html" title="C# Sınıflar, Nesneler ve Metotlar: ref ve out ile Nesne Modelini Anlamak" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-siniflar-nesneler-ve-metotlar-ref-ve-out-ile-nesne-modelini-anlamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-siniflar-nesneler-ve-metotlar-ref-ve-out-ile-nesne-modelini-anlamak/"><![CDATA[<p><img src="/img/c-siniflar-nesneler-62.svg" alt="c-siniflar-nesneler-62" /></p>

<p>Bir banka hesabını programlamak istediğinizi düşünün: hesabın bakiyesi vardır, para çekilebilir ve işlemin sonucu öğrenilebilir. C# bu dünyayı sınıflar, nesneler ve metotlarla temsil eder. İşin eğlenceli kısmı, aynı hesaba iki farklı değişkenle ulaşabilmenizdir. Ancak bir nesneyi değiştirmekle, değişkenin gösterdiği nesneyi değiştirmek aynı şey değildir!</p>

<p>``</p>

<h2 id="sınıf-plan-nesne-çalışan-örnektir">Sınıf plan, nesne çalışan örnektir</h2>

<p><strong>Sınıf</strong>, verileri ve davranışları bir araya getiren tür tanımıdır. <strong>Nesne</strong>, bu sınıftan oluşturulan somut örnektir. <strong>Metot</strong> ise bir nesnenin gerçekleştirebildiği işlemi tanımlar; ayrıca sınıfa ait statik metotlar da bulunabilir.</p>

<p>Bir sınıftan oluşturulan iki nesnenin bakiyeleri birbirinden bağımsız olabilir. Buna karşılık iki değişken aynı nesneye bağlanabilir. Aynı televizyonu yöneten iki kumanda düşünün: kumandalar farklıdır, fakat değiştirilen televizyon aynıdır.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Banka örneği</th>
      <th>Görevi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sınıf</td>
      <td><code class="language-plaintext highlighter-rouge">Hesap</code></td>
      <td>Yapıyı ve davranışları tanımlar</td>
    </tr>
    <tr>
      <td>Nesne</td>
      <td>Oluşturulan müşteri hesabı</td>
      <td>Durumu taşır</td>
    </tr>
    <tr>
      <td>Özellik</td>
      <td><code class="language-plaintext highlighter-rouge">Bakiye</code></td>
      <td>Veriye kontrollü erişim sağlar</td>
    </tr>
    <tr>
      <td>Metot</td>
      <td><code class="language-plaintext highlighter-rouge">ParaCek</code></td>
      <td>İşlem gerçekleştirir</td>
    </tr>
  </tbody>
</table>

<p>C# sınıfları <strong>referans türüdür</strong>. Bir sınıf değişkeninin değeri, nesnenin kendisi değil, ona erişmeyi sağlayan referanstır. Referansı kopyalamak, nesneyi çoğaltmaz.</p>

<h2 id="durumu-davranışla-korumak">Durumu davranışla korumak</h2>

<p>Aşağıdaki sınıf, bakiyenin dışarıdan doğrudan değiştirilmesini engeller. Kurucu metot başlangıç durumunu oluşturur; <code class="language-plaintext highlighter-rouge">ParaCek</code> ise çekim kurallarını uygular ve sonucu bildirir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">Hesap</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">decimal</span> <span class="n">Bakiye</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="nf">Hesap</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">bakiye</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">bakiye</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentOutOfRangeException</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="n">bakiye</span><span class="p">));</span>

        <span class="n">Bakiye</span> <span class="p">=</span> <span class="n">bakiye</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="kt">bool</span> <span class="nf">ParaCek</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">tutar</span><span class="p">,</span> <span class="k">out</span> <span class="kt">decimal</span> <span class="n">kalan</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">kalan</span> <span class="p">=</span> <span class="n">Bakiye</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">tutar</span> <span class="p">&lt;=</span> <span class="m">0</span> <span class="p">||</span> <span class="n">tutar</span> <span class="p">&gt;</span> <span class="n">Bakiye</span><span class="p">)</span>
            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>

        <span class="n">Bakiye</span> <span class="p">-=</span> <span class="n">tutar</span><span class="p">;</span>
        <span class="n">kalan</span> <span class="p">=</span> <span class="n">Bakiye</span><span class="p">;</span>
        <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">private set</code>, bakiyenin yalnızca sınıf içinden atanabilmesini sağlar. Bu yaklaşım <strong>kapsülleme</strong> olarak adlandırılır: veriyi saklamaktan çok, geçerli durumları korumak önemlidir. Negatif başlangıç bakiyesi reddedilir; geçersiz çekim ise hesabı değiştirmez.</p>

<p>Başarılı çekimin matematiksel modeli şöyledir:</p>

\[B_{son} = B_{ilk} - T\]

<p>Burada $T$ çekilen tutardır; işlemin kabul koşulu $0 &lt; T \leq B_{ilk}$ şeklindedir. Kod, bu koşulu denetleyerek nesnenin tutarlılığını korur. Para hesaplarında <code class="language-plaintext highlighter-rouge">decimal</code>, ondalık değerleri temsil etmek için genellikle <code class="language-plaintext highlighter-rouge">double</code> türünden daha uygundur.</p>

<h2 id="varsayılan-aktarım-ref-ve-out">Varsayılan aktarım, ref ve out</h2>

<p>C# parametreleri varsayılan olarak <strong>değer ile</strong> aktarır. <code class="language-plaintext highlighter-rouge">decimal</code> parametresinde sayısal değer kopyalanır. <code class="language-plaintext highlighter-rouge">Hesap</code> parametresinde ise referansın değeri kopyalanır. Bu yüzden normal bir parametre üzerinden nesnenin özelliklerini değiştirmek mümkündür; bunun için <code class="language-plaintext highlighter-rouge">ref</code> gerekmez.</p>

<p>Ancak metot içinde normal parametreye <code class="language-plaintext highlighter-rouge">new Hesap(...)</code> atamak, çağıranın değişkenini başka nesneye yönlendirmez. Yalnızca parametrenin yerel kopyası değişir. İşte <code class="language-plaintext highlighter-rouge">ref</code>, çağıranın değişkenine erişim sağlayarak bu ayrımı görünür kılar.</p>

<table>
  <thead>
    <tr>
      <th>Aktarım</th>
      <th>Çağrıdan önce değer gerekli mi?</th>
      <th>Metodun atama zorunluluğu</th>
      <th>Amaç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Normal</td>
      <td>Evet</td>
      <td>Yok</td>
      <td>Değerin kopyasıyla çalışmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ref</code></td>
      <td>Evet</td>
      <td>Yok</td>
      <td>Mevcut değişkeni okuyup değiştirmek</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">out</code></td>
      <td>Hayır</td>
      <td>Her normal dönüş yolunda var</td>
      <td>Sonuç üretmek</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">ref</code> ve <code class="language-plaintext highlighter-rouge">out</code>, hem metot bildiriminde hem çağrıda belirtilir. <code class="language-plaintext highlighter-rouge">out</code> parametresi, metot içinde okunmadan önce atanmalıdır. Örneğimizde <code class="language-plaintext highlighter-rouge">kalan</code> başlangıçta atanır; böylece başarısız çekimde bile kullanılabilir bir sonuç döner.</p>

<h2 id="referansı-değiştirmek-başka-bir-iştir">Referansı değiştirmek başka bir iştir</h2>

<p>.NET 6+ konsol projesinde aşağıdaki üst düzey kullanım kodunu sınıf bildiriminden önce yerleştirebilirsiniz:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">hesap</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Hesap</span><span class="p">(</span><span class="m">100m</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">ortak</span> <span class="p">=</span> <span class="n">hesap</span><span class="p">;</span>

<span class="kt">bool</span> <span class="n">basarili</span> <span class="p">=</span> <span class="n">hesap</span><span class="p">.</span><span class="nf">ParaCek</span><span class="p">(</span><span class="m">30m</span><span class="p">,</span> <span class="k">out</span> <span class="kt">decimal</span> <span class="n">kalan</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">$"Başarılı: </span><span class="p">{</span><span class="n">basarili</span><span class="p">}</span><span class="s">, kalan: </span><span class="p">{</span><span class="n">kalan</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>

<span class="n">ortak</span><span class="p">.</span><span class="nf">ParaCek</span><span class="p">(</span><span class="m">10m</span><span class="p">,</span> <span class="k">out</span> <span class="n">kalan</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">hesap</span><span class="p">.</span><span class="n">Bakiye</span><span class="p">);</span> <span class="c1">// 60</span>

<span class="nf">Yenile</span><span class="p">(</span><span class="k">ref</span> <span class="n">hesap</span><span class="p">);</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">hesap</span><span class="p">.</span><span class="n">Bakiye</span><span class="p">);</span> <span class="c1">// 0</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">ortak</span><span class="p">.</span><span class="n">Bakiye</span><span class="p">);</span> <span class="c1">// 60</span>

<span class="k">static</span> <span class="k">void</span> <span class="nf">Yenile</span><span class="p">(</span><span class="k">ref</span> <span class="n">Hesap</span> <span class="n">hedef</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">hedef</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Hesap</span><span class="p">(</span><span class="m">0m</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>İlk atamada <code class="language-plaintext highlighter-rouge">ortak</code> ve <code class="language-plaintext highlighter-rouge">hesap</code> aynı nesneyi gösterir. Dolayısıyla <code class="language-plaintext highlighter-rouge">ortak</code> üzerinden yapılan çekim, <code class="language-plaintext highlighter-rouge">hesap</code> üzerinden görülen bakiyeyi de değiştirir. <code class="language-plaintext highlighter-rouge">Yenile</code> ise <code class="language-plaintext highlighter-rouge">ref</code> sayesinde doğrudan <code class="language-plaintext highlighter-rouge">hesap</code> değişkeninin referansını değiştirir. <code class="language-plaintext highlighter-rouge">ortak</code>, eski nesneyi göstermeyi sürdürür; nesne topluca sıfırlanmamıştır.</p>

<h2 id="küçük-bir-seçim-rehberi">Küçük bir seçim rehberi</h2>

<p>Tek sonuç için çoğunlukla dönüş değerini kullanın. Başarı bilgisiyle ek sonuç gerekiyorsa <code class="language-plaintext highlighter-rouge">out</code> kullanışlıdır; <code class="language-plaintext highlighter-rouge">int.TryParse</code> bunun klasik örneğidir. Çağıranın mevcut değişkenini değiştirmek gerekiyorsa <code class="language-plaintext highlighter-rouge">ref</code> düşünülebilir. Son kontrol sorunuz şu olsun: “Nesnenin durumunu mu, değişkenin değerini mi değiştiriyorum?” Bu ayrım, referans karmaşasının büyük bölümünü çözer.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="nesne-yönelimli-programlama" /><category term="sınıflar" /><category term="nesneler" /><category term="metotlar" /><category term="ref" /><category term="out" /><summary type="html"><![CDATA[Bir banka hesabını programlamak istediğinizi düşünün: hesabın bakiyesi vardır, para çekilebilir ve işlemin sonucu öğrenilebilir. C# bu dünyayı sınıflar, nesneler ve metotlarla temsil eder. İşin eğlenceli kısmı, aynı hesaba iki farklı değişkenle ulaşabilmenizdir. Ancak bir nesneyi değiştirmekle, değişkenin gösterdiği nesneyi değiştirmek aynı şey değildir!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-siniflar-nesneler-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-siniflar-nesneler-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Çamaşır Makinesi Konuşursa: Titreşim Verisinden Uzaktan İzleme ve Arıza Tahmini</title><link href="https://program.sonsuz.us/posts/camasir-makinesi-konusursa-titresim-verisinden-uzaktan-izleme-ve-ariza-tahmini/" rel="alternate" type="text/html" title="Çamaşır Makinesi Konuşursa: Titreşim Verisinden Uzaktan İzleme ve Arıza Tahmini" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/camasir-makinesi-konusursa-titresim-verisinden-uzaktan-izleme-ve-ariza-tahmini</id><content type="html" xml:base="https://program.sonsuz.us/posts/camasir-makinesi-konusursa-titresim-verisinden-uzaktan-izleme-ve-ariza-tahmini/"><![CDATA[<p>Çamaşır makineniz sıkma sırasında banyoda yürüyüşe çıkıyorsa, size bir şey anlatmaya çalışıyor olabilir. Akıllı beyaz eşyalarda titreşim sensörleri bu mekanik dili sayılara çevirir. Amaç yalnızca “makine sallanıyor” demek değil; normal davranıştan sapmayı yakalayarak bakım ihtiyacını, ciddi bir arıza oluşmadan önce görünür kılmaktır.</p>

<p>``</p>

<h2 id="titreşim-neden-değerli-bir-ipucudur">Titreşim neden değerli bir ipucudur?</h2>

<p>Dönen tambur, motor, rulmanlar ve amortisörler farklı titreşim bileşenleri üretir. Dengesiz yük, dönme frekansı çevresindeki hareketi artırabilir; rulman hasarı ise darbe benzeri bileşenler oluşturabilir. Ancak aynı belirti birden fazla nedenden kaynaklanır. Sensörümüz dedektiftir, kahin değil!</p>

<p>Dakikada 1200 devir yapan tamburun dönme frekansı $1200/60=20\,\text{Hz}$ olur. Frekans analizi, titreşim enerjisinin hangi bölgelerde yoğunlaştığını gösterir. Bu bilgi, toplam titreşim seviyesinden daha açıklayıcı olabilir.</p>

<table>
  <thead>
    <tr>
      <th>Gözlenen değişim</th>
      <th>Olası açıklama</th>
      <th>Kontrol edilmesi gereken</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Dönme frekansında artış</td>
      <td>Yük dengesizliği</td>
      <td>Çamaşır dağılımı</td>
    </tr>
    <tr>
      <td>Darbe benzeri sinyaller</td>
      <td>Rulman veya mekanik temas</td>
      <td>Tekrarlama ve çalışma koşulları</td>
    </tr>
    <tr>
      <td>Genel titreşim artışı</td>
      <td>Süspansiyon veya kurulum sorunu</td>
      <td>Zemin ve ayak dengesi</td>
    </tr>
  </tbody>
</table>

<p>Bunlar kesin teşhis değildir. Aynı makine, aynı hızda bile farklı yüklerle farklı davranabilir.</p>

<h2 id="önce-doğru-veriyi-toplayalım">Önce doğru veriyi toplayalım</h2>

<p>Bir ivmeölçer, üretici önerilerine uygun ve güvenli bir gövde noktasına sabitlenebilir. Sensörün konumu ve montajı değişirse referans da değişir. Elektrik veya hareketli parçalar çevresindeki müdahaleler uzmanlık gerektirir.</p>

<p>Örnekleme hızı, ilgilenilen en yüksek frekansın iki katından büyük olmalıdır: $f_s&gt;2f_{\max}$. Pratikte uygun kenar payı ve örnekleme öncesi anti-aliasing filtresi gerekir. Örneğin 2 kHz örnekleme, aşağıdaki örnekte kullanılan 300–800 Hz bandını incelemeye uygundur; bu bant her makine için evrensel değildir.</p>

<p>İki saniyelik pencerelerde üç özellik çıkaralım: RMS, basıklık ve bant enerjisi oranı. RMS genel titreşim seviyesini özetler:</p>

\[a_{RMS}=\sqrt{\frac{1}{N}\sum_{i=1}^{N}a_i^2}\]

<p>Basıklık, darbe karakterine duyarlıdır. Bant enerjisi oranı ise seçilen frekans bölgesinin toplam güç içindeki payını gösterir. Öncesinde sinyal ortalamasını çıkararak sabit bileşeni azaltırız.</p>

<h2 id="python-ile-küçük-bir-erken-uyarı-motoru">Python ile küçük bir erken uyarı motoru</h2>

<p>Aşağıdaki kod, tek eksenli ivme penceresinden özellik çıkarır. Sağlıklı çalışma pencerelerinden hazırlanmış <code class="language-plaintext highlighter-rouge">referans</code> matrisiyle karşılaştırarak bir anomali puanı üretir. Her referans satırı aynı üç özelliği içermelidir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">from</span> <span class="n">scipy.signal</span> <span class="kn">import</span> <span class="n">welch</span>
<span class="kn">from</span> <span class="n">scipy.stats</span> <span class="kn">import</span> <span class="n">kurtosis</span>


<span class="k">def</span> <span class="nf">ozellikler</span><span class="p">(</span><span class="n">ivme</span><span class="p">,</span> <span class="n">fs</span><span class="o">=</span><span class="mi">2000</span><span class="p">):</span>
    <span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">asarray</span><span class="p">(</span><span class="n">ivme</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">float</span><span class="p">)</span>
    <span class="n">a</span> <span class="o">=</span> <span class="n">a</span> <span class="o">-</span> <span class="n">a</span><span class="p">.</span><span class="nf">mean</span><span class="p">()</span>
    <span class="n">f</span><span class="p">,</span> <span class="n">p</span> <span class="o">=</span> <span class="nf">welch</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">fs</span><span class="o">=</span><span class="n">fs</span><span class="p">,</span> <span class="n">nperseg</span><span class="o">=</span><span class="nf">min</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">a</span><span class="p">),</span> <span class="mi">1024</span><span class="p">))</span>
    <span class="n">bant</span> <span class="o">=</span> <span class="p">(</span><span class="n">f</span> <span class="o">&gt;=</span> <span class="mi">300</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">f</span> <span class="o">&lt;=</span> <span class="mi">800</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span>
        <span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">(</span><span class="n">a</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)),</span>
        <span class="nf">kurtosis</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">fisher</span><span class="o">=</span><span class="bp">False</span><span class="p">),</span>
        <span class="n">p</span><span class="p">[</span><span class="n">bant</span><span class="p">].</span><span class="nf">sum</span><span class="p">()</span> <span class="o">/</span> <span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="nf">sum</span><span class="p">()</span> <span class="o">+</span> <span class="mf">1e-12</span><span class="p">)</span>
    <span class="p">])</span>


<span class="k">def</span> <span class="nf">alarm_puani</span><span class="p">(</span><span class="n">ivme</span><span class="p">,</span> <span class="n">referans</span><span class="p">,</span> <span class="n">fs</span><span class="o">=</span><span class="mi">2000</span><span class="p">):</span>
    <span class="n">ref</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">asarray</span><span class="p">(</span><span class="n">referans</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">float</span><span class="p">)</span>
    <span class="n">medyan</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">median</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">mad</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">median</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">abs</span><span class="p">(</span><span class="n">ref</span> <span class="o">-</span> <span class="n">medyan</span><span class="p">),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">z</span> <span class="o">=</span> <span class="p">(</span><span class="nf">ozellikler</span><span class="p">(</span><span class="n">ivme</span><span class="p">,</span> <span class="n">fs</span><span class="p">)</span> <span class="o">-</span> <span class="n">medyan</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="mf">1.4826</span> <span class="o">*</span> <span class="n">mad</span> <span class="o">+</span> <span class="mf">1e-6</span><span class="p">)</span>
    <span class="k">return</span> <span class="nf">float</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">maximum</span><span class="p">(</span><span class="n">z</span><span class="p">,</span> <span class="mi">0</span><span class="p">).</span><span class="nf">max</span><span class="p">())</span>
</code></pre></div></div>

<p>Medyan ve MAD, uç değerlerin referansı bozmasını azaltır. Puan yalnızca referansın üzerindeki sapmaları toplar; arıza olasılığı değildir. Sabit veya geçersiz sensör verileri ayrıca filtrelenmeli, çok küçük MAD değerleri için özellik bazında ölçek tabanları belirlenmelidir.</p>

<h2 id="veriyi-değil-anlamını-gönderelim">Veriyi değil, anlamını gönderelim</h2>

<p>Sensör verisi önce yerel işlemcide özetlenebilir. Özellikler, tambur hızı, program aşaması ve zaman damgasıyla MQTT üzerinden TLS kullanılarak sunucuya iletilir. Cihaz kimlik doğrulaması ve erişim yetkileri de şarttır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Bedel</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ham veriyi buluta gönderme</td>
      <td>Ayrıntılı sonradan analiz</td>
      <td>Yüksek trafik ve depolama</td>
    </tr>
    <tr>
      <td>Yerelde özellik çıkarma</td>
      <td>Düşük trafik, hızlı tepki</td>
      <td>Bazı ayrıntıların kaybı</td>
    </tr>
  </tbody>
</table>

<p>Bağlantı kesilirse yerel tampon kullanılabilir. Böylece internetin molası, izleme sisteminin hafızasını silmez.</p>

<h2 id="alarmdan-gerçek-tahmine-geçiş">Alarmdan gerçek tahmine geçiş</h2>

<p>Referansları program, yük ve hız koşullarına göre ayırmak gerekir. Tek bir yüksek puan yerine birkaç karşılaştırılabilir pencerede kalıcı artış aranmalıdır. Eşikler gerçek saha verisiyle ayarlanır; yanlış alarm oranı ve bakım öncesi uyarı süresi birlikte ölçülür.</p>

<p>Gerçek kestirimci bakım için zaman içindeki eğilimler, servis kayıtları ve doğrulanmış arıza etiketleri gerekir. Bakım sonrası titreşimin normale dönmesi de değerli geri bildirimdir. Yalnızca titreşimden “rulman üç gün sonra bozulacak” demek güvenilir değildir. Başarılı sistem, gerektiğinde “alışılmadık bir değişim var, kontrol ettirelim” diyendir. Banyonun yeni dansçısını erken fark etmek bile iyi bir başlangıçtır!</p>

<p><img src="/img/camasir-makinesi-konusursa-94.svg" alt="camasir-makinesi-konusursa-94" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="iot" /><category term="kestirimci bakım" /><category term="titreşim analizi" /><category term="python" /><category term="akıllı beyaz eşya" /><category term="uzaktan izleme" /><summary type="html"><![CDATA[Çamaşır makineniz sıkma sırasında banyoda yürüyüşe çıkıyorsa, size bir şey anlatmaya çalışıyor olabilir. Akıllı beyaz eşyalarda titreşim sensörleri bu mekanik dili sayılara çevirir. Amaç yalnızca “makine sallanıyor” demek değil; normal davranıştan sapmayı yakalayarak bakım ihtiyacını, ciddi bir arıza oluşmadan önce görünür kılmaktır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/camasir-makinesi-konusursa-94.png" /><media:content medium="image" url="https://program.sonsuz.us/img/camasir-makinesi-konusursa-94.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Deterministik Lockstep: RTS Ordularını Aynı Ritme Sokmak</title><link href="https://program.sonsuz.us/posts/deterministik-lockstep-rts-ordularini-ayni-ritme-sokmak/" rel="alternate" type="text/html" title="Deterministik Lockstep: RTS Ordularını Aynı Ritme Sokmak" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/deterministik-lockstep-rts-ordularini-ayni-ritme-sokmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/deterministik-lockstep-rts-ordularini-ayni-ritme-sokmak/"><![CDATA[<p>Ekranda bin asker yürürken her askerin konumunu sürekli diğer oyunculara göndermek, ağı dijital bir trafik sıkışıklığına çevirebilir. Gerçek zamanlı strateji oyunlarının klasik çözümü daha zariftir: Dünyayı değil, oyuncuların verdiği emirleri paylaşmak. Deterministik lockstep yaklaşımında herkes aynı tarifle aynı yemeği pişirir; tek şart, kimsenin gizlice fazladan tuz atmamasıdır.</p>

<p>``</p>

<h2 id="temel-fikir-aynı-başlangıç-aynı-sonuç">Temel fikir: Aynı başlangıç, aynı sonuç</h2>

<p>Her istemci, oyun dünyasının tamamını yerel olarak simüle eder. Ağ üzerinden genellikle “birlikleri şu noktaya gönder” veya “kışla inşa et” gibi komutlar taşınır. Başlangıç durumu ve işlenen komutlar aynıysa, simülasyonun her bilgisayarda aynı sonucu üretmesi beklenir.</p>

<p>Bunu şu bağıntıyla düşünebiliriz:</p>

\[S_{k+1}=F(S_k,C_k)\]

<p>Burada $S_k$ dünya durumu, $C_k$ ilgili simülasyon adımının sıralanmış komutları, $F$ ise deterministik güncelleme fonksiyonudur. Lockstep, istemcilerin aynı adım için gereken komutlar tamamlanmadan ilerlememesini sağlar. Determinizm ise ilerlediklerinde aynı yere ulaşmalarını sağlar. Bu iki kavram birbirinin yerine geçmez.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Ağda taşınan</th>
      <th>Temel bedel</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Durum senkronizasyonu</td>
      <td>Konumlar ve durum güncellemeleri</td>
      <td>Daha fazla bant genişliği</td>
    </tr>
    <tr>
      <td>Deterministik lockstep</td>
      <td>Oyuncu komutları</td>
      <td>Determinizm ve bekleme yönetimi</td>
    </tr>
  </tbody>
</table>

<h2 id="determinizm-neden-zor">Determinizm neden zor?</h2>

<p>“Aynı kod çalışıyor, sonuç da aynıdır” düşüncesi burada tehlikelidir. Kayan noktalı hesaplamalar; işlemci, derleyici optimizasyonu veya matematik kütüphanesine göre farklılaşabilir. Küçük bir sapma, yüzlerce adım sonra iki istemcide farklı savaş sonuçları doğurabilir.</p>

<p>Bu yüzden kritik hesaplarda tam sayı veya sabit noktalı aritmetik tercih edilebilir. Sabit noktalı temsil, örneğin bir metreyi 1000 birim olarak saklar. Ancak taşma ve yuvarlama kuralları da tutarlı olmalıdır; yalnızca veri tipini değiştirmek sihirli çözüm değildir.</p>

<p>Rastgelelik de yasak değildir: Aynı algoritma, başlangıç tohumu ve çağrı sırası kullanılmalıdır. Koleksiyon dolaşım sırası, yol bulmadaki eşitlik kararları ve paralel işlerin tamamlanma sırası da sabitlenmelidir. Simülasyona duvar saati, değişken kare süresi veya yerel görsel efektlerden karar taşımayın.</p>

<h2 id="i̇nternet-bekler-simülasyon-sayar">İnternet bekler, simülasyon sayar</h2>

<p>Simülasyon sabit zaman adımlarıyla ilerler: $t_k=k\Delta t$. Ekran çizimi daha hızlı olabilir; aradaki görüntüler enterpolasyonla yumuşatılabilir. Böylece 30 simülasyon adımıyla çalışan bir oyun, 144 Hz ekranda akıcı görünebilir.</p>

<p>Oyuncunun emri çoğunlukla mevcut adıma değil, birkaç adım sonrasına atanır. Bu giriş gecikmesi, paketlerin ulaşması için zaman kazandırır. Tamamlanan her oyuncu paketi, emir yoksa bile boş bir komut listesi içermelidir. Aksi halde “oyuncu hiçbir şey yapmadı” ile “paket henüz gelmedi” ayırt edilemez.</p>

<table>
  <thead>
    <tr>
      <th>Tampon</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Küçük</td>
      <td>Daha hızlı komut tepkisi</td>
      <td>Ağ dalgalanmasında daha çok bekleme</td>
    </tr>
    <tr>
      <td>Büyük</td>
      <td>Daha kararlı ilerleme</td>
      <td>Daha belirgin giriş gecikmesi</td>
    </tr>
  </tbody>
</table>

<p>Paket kaybında yeniden gönderim gerekir. Komutlar adım ve oyuncu kimliğiyle eşleştirilmeli, tekrar gelenler ayıklanmalıdır. Geç kalan oyuncuyu sonsuza kadar beklemek yerine zaman aşımı ve bağlantı koparma politikası da tasarlanmalıdır.</p>

<h2 id="küçük-bir-lockstep-çekirdeği">Küçük bir lockstep çekirdeği</h2>

<p>Aşağıdaki Python örneği, ağ katmanının doğrulanmış ve eksiksiz oyuncu paketlerini <code class="language-plaintext highlighter-rouge">inbox[adım][oyuncu]</code> yapısına koyduğunu varsayar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">step_tick</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">tick</span><span class="p">,</span> <span class="n">inbox</span><span class="p">,</span> <span class="n">players</span><span class="p">,</span> <span class="n">advance_fixed</span><span class="p">):</span>
    <span class="n">bundles</span> <span class="o">=</span> <span class="n">inbox</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">tick</span><span class="p">,</span> <span class="p">{})</span>
    <span class="k">if</span> <span class="nf">set</span><span class="p">(</span><span class="n">bundles</span><span class="p">)</span> <span class="o">!=</span> <span class="nf">set</span><span class="p">(</span><span class="n">players</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">player</span> <span class="ow">in</span> <span class="nf">sorted</span><span class="p">(</span><span class="n">players</span><span class="p">):</span>
        <span class="n">commands</span> <span class="o">=</span> <span class="nf">sorted</span><span class="p">(</span>
            <span class="n">bundles</span><span class="p">[</span><span class="n">player</span><span class="p">],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">command</span><span class="p">:</span> <span class="n">command</span><span class="p">[</span><span class="sh">'</span><span class="s">seq</span><span class="sh">'</span><span class="p">]</span>
        <span class="p">)</span>
        <span class="k">for</span> <span class="n">command</span> <span class="ow">in</span> <span class="n">commands</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">command</span><span class="p">[</span><span class="sh">'</span><span class="s">kind</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="sh">'</span><span class="s">move</span><span class="sh">'</span><span class="p">:</span>
                <span class="n">unit</span> <span class="o">=</span> <span class="n">state</span><span class="p">[</span><span class="sh">'</span><span class="s">units</span><span class="sh">'</span><span class="p">][</span><span class="n">command</span><span class="p">[</span><span class="sh">'</span><span class="s">unit</span><span class="sh">'</span><span class="p">]]</span>
                <span class="n">unit</span><span class="p">[</span><span class="sh">'</span><span class="s">target</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">command</span><span class="p">[</span><span class="sh">'</span><span class="s">x</span><span class="sh">'</span><span class="p">],</span> <span class="n">command</span><span class="p">[</span><span class="sh">'</span><span class="s">y</span><span class="sh">'</span><span class="p">])</span>

    <span class="nf">advance_fixed</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
    <span class="k">del</span> <span class="n">inbox</span><span class="p">[</span><span class="n">tick</span><span class="p">]</span>
    <span class="k">return</span> <span class="bp">True</span>
</code></pre></div></div>

<p>Fonksiyon eksik paket varsa durur; aksi halde komutları ortak sırayla uygular ve dünyayı bir adım ilerletir. Çağıran döngü, yalnızca <code class="language-plaintext highlighter-rouge">True</code> sonucunda adım sayacını artırmalıdır. <code class="language-plaintext highlighter-rouge">advance_fixed</code> hareketi, çatışmayı ve kaynak üretimini deterministik biçimde yürütür. Gerçek uygulamada birim sahipliği, hedef geçerliliği ve sıra numarası benzersizliği ayrıca denetlenmelidir.</p>

<h2 id="senkron-kaymasını-yakalamak">Senkron kaymasını yakalamak</h2>

<p>Belirli aralıklarla dünya durumunun özeti karşılaştırılabilir. Ancak bellekteki ham nesneleri veya Python’ın yerleşik <code class="language-plaintext highlighter-rouge">hash()</code> sonucunu kullanmak güvenilir değildir. Birimleri kimliklerine göre sıralayıp alanları tanımlı bir biçimde serileştirerek kararlı bir özet üretin.</p>

<p>Özetler farklıysa bir desync vardır. İlk ayrışan adımı bulmak için başlangıç durumunu, komut günlüğünü ve ara özetleri saklamak çok değerlidir. Kurtarma gerekiyorsa güvenilir bir referans durumdan yeniden yükleme düşünülebilir; özet karşılaştırması tek başına hatayı düzeltmez.</p>

<p>Lockstep’in ödülü, binlerce birimin sürekli durum aktarımı olmadan birlikte çalışabilmesidir. Bedeli ise titiz mühendisliktir. Kısacası ağdan orduyu taşımayın; emirleri taşıyın ve bütün generallerin aynı kurallarla düşündüğünden emin olun.</p>

<p><img src="/img/deterministik-lockstep-rts-47.svg" alt="deterministik-lockstep-rts-47" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="oyun geliştirme" /><category term="ağ programlama" /><category term="deterministik lockstep" /><category term="rts" /><category term="senkronizasyon" /><category term="simülasyon" /><summary type="html"><![CDATA[Ekranda bin asker yürürken her askerin konumunu sürekli diğer oyunculara göndermek, ağı dijital bir trafik sıkışıklığına çevirebilir. Gerçek zamanlı strateji oyunlarının klasik çözümü daha zariftir: Dünyayı değil, oyuncuların verdiği emirleri paylaşmak. Deterministik lockstep yaklaşımında herkes aynı tarifle aynı yemeği pişirir; tek şart, kimsenin gizlice fazladan tuz atmamasıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/deterministik-lockstep-rts-47.png" /><media:content medium="image" url="https://program.sonsuz.us/img/deterministik-lockstep-rts-47.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dijital Karakterlerin Derdi Ne? Simülasyon Oyunlarında Yapay Yaşam</title><link href="https://program.sonsuz.us/posts/dijital-karakterlerin-derdi-ne-simulasyon-oyunlarinda-yapay-yasam/" rel="alternate" type="text/html" title="Dijital Karakterlerin Derdi Ne? Simülasyon Oyunlarında Yapay Yaşam" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/dijital-karakterlerin-derdi-ne-simulasyon-oyunlarinda-yapay-yasam</id><content type="html" xml:base="https://program.sonsuz.us/posts/dijital-karakterlerin-derdi-ne-simulasyon-oyunlarinda-yapay-yasam/"><![CDATA[<p><img src="/img/dijital-karakterlerin-derdi-34.svg" alt="dijital-karakterlerin-derdi-34" /></p>

<p>Bir karakter düşünün: Karnı aç, uykusu var, ama komşusuyla dedikodu yapmayı da bırakamıyor. Simülasyon oyunlarını eğlenceli kılan tam olarak bu küçük çelişkilerdir. The Sims benzeri oyunlarda karakterler, yalnızca hazır animasyonlar oynatan kuklalar değildir; ihtiyaçları, çevresel fırsatları ve karar kuralları sayesinde yaşayan bir mahalle izlenimi yaratırlar.</p>

<p>``</p>

<h2 id="yapay-yaşam-bilinç-değil-etkileşim">Yapay yaşam: Bilinç değil, etkileşim</h2>

<p><strong>Yapay yaşam</strong>, canlı sistemlerin bazı özelliklerini hesaplamalı modellerle yeniden üretmeyi amaçlar. Oyunlarda bunun karşılığı; ihtiyaçları değişen, çevresini algılayan ve eylemlerinin sonuçlarından etkilenen ajanlardır. Buradaki ajan, kendi durumunu taşıyan bir karakterdir.</p>

<p>İnandırıcılık için insan zihnini bütünüyle simüle etmek gerekmez. Basit kuralların birleşmesiyle <strong>ortaya çıkan davranışlar</strong> üretilebilir: Aynı buzdolabına yönelen iki karakterden biri bekler, diğeri sohbet eder. Küçük bir kaynak çatışması, oyuncunun gözünde komik bir hikâyeye dönüşür.</p>

<p>Aşağıdaki model, bu yaklaşımı öğretmek içindir; The Sims’in gerçek kaynak kodunun birebir açıklaması değildir.</p>

<h2 id="i̇htiyaçları-sayılara-çevirmek">İhtiyaçları sayılara çevirmek</h2>

<p>Her ihtiyacı $n_i$ ile gösterelim. Değerler sıfır ile bir arasında olsun: Sıfır, ihtiyaç karşılanmış; bir, ciddi eksiklik demektir. Böylece açlık ve enerji eksikliği aynı ölçekte karşılaştırılabilir.</p>

<table>
  <thead>
    <tr>
      <th>İhtiyaç eksikliği</th>
      <th>Zamanla değişim</th>
      <th>Azaltan eylem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Açlık</td>
      <td>Genellikle yükselir</td>
      <td>Yemek yemek</td>
    </tr>
    <tr>
      <td>Enerji</td>
      <td>Uyanıkken yükselir</td>
      <td>Uyumak</td>
    </tr>
    <tr>
      <td>Sosyallik</td>
      <td>Yalnızlıkla yükselir</td>
      <td>Sohbet etmek</td>
    </tr>
  </tbody>
</table>

<p>Basit bir zaman güncellemesi şöyle yazılır:</p>

\[n_i(t+h)=\min(1,n_i(t)+r_i h)\]

<p>Burada $h$ geçen süre, $r_i$ ise saniye başına artış hızıdır. Eylem tamamlandığında ilgili eksiklik azaltılır ve değer sıfırın altına düşmeyecek şekilde sınırlandırılır. Gerçek projelerde uyku gibi uzun eylemlerin etkisini tamamlanma anında değil, zaman boyunca uygulamak daha doğal sonuç verir.</p>

<h2 id="karar-vermek-en-faydalı-eylem-hangisi">Karar vermek: En faydalı eylem hangisi?</h2>

<p><strong>Utility AI</strong>, uygulanabilir eylemlere fayda puanı vererek seçim yapar. Basit bir puanlama kullanabiliriz:</p>

\[U(a)=\sum_i w_i n_i\min(n_i,d_i(a))-\lambda T(a)\]

<p>$w_i$ ihtiyacın önemini, $d_i(a)$ eylemin sağlayacağı azalmayı, $T(a)$ süresini temsil eder. Minimum işlemi, zaten karşılanmış bir ihtiyaca gereğinden fazla fayda yazılmasını önler. Süre cezası ise uzak mutfağa yürümek gibi maliyetleri hesaba katabilir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Güçlü yanı</th>
      <th>Zorlandığı nokta</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sabit öncelikler</td>
      <td>Kolay uygulanır</td>
      <td>Davranışlar tekrara düşebilir</td>
    </tr>
    <tr>
      <td>Sonlu durum makinesi</td>
      <td>Geçişler nettir</td>
      <td>Çok ihtiyaçta karmaşıklaşır</td>
    </tr>
    <tr>
      <td>Utility AI</td>
      <td>Öncelikler dinamik değişir</td>
      <td>Puanları dikkatle ayarlamak gerekir</td>
    </tr>
  </tbody>
</table>

<h2 id="python-ile-küçük-bir-karar-motoru">Python ile küçük bir karar motoru</h2>

<p>Aşağıdaki örnek, önceden uygulanabilir olduğu belirlenmiş eylemler arasından seçim yapar. Karakterin mevcut eylemini değiştirmek için küçük bir avantaj eşiği kullanır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>

<span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">Action</span><span class="p">:</span>
    <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
    <span class="n">relief</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">float</span><span class="p">]</span>
    <span class="n">seconds</span><span class="p">:</span> <span class="nb">float</span>

<span class="n">weights</span> <span class="o">=</span> <span class="p">{</span><span class="sh">"</span><span class="s">hunger</span><span class="sh">"</span><span class="p">:</span> <span class="mf">1.4</span><span class="p">,</span> <span class="sh">"</span><span class="s">energy</span><span class="sh">"</span><span class="p">:</span> <span class="mf">1.2</span><span class="p">,</span> <span class="sh">"</span><span class="s">social</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.8</span><span class="p">}</span>
<span class="n">needs</span> <span class="o">=</span> <span class="p">{</span><span class="sh">"</span><span class="s">hunger</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.8</span><span class="p">,</span> <span class="sh">"</span><span class="s">energy</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.5</span><span class="p">,</span> <span class="sh">"</span><span class="s">social</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.3</span><span class="p">}</span>

<span class="n">actions</span> <span class="o">=</span> <span class="p">[</span>
    <span class="nc">Action</span><span class="p">(</span><span class="sh">"</span><span class="s">yemek</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">hunger</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.6</span><span class="p">},</span> <span class="mi">8</span><span class="p">),</span>
    <span class="nc">Action</span><span class="p">(</span><span class="sh">"</span><span class="s">uyumak</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">energy</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.7</span><span class="p">},</span> <span class="mi">30</span><span class="p">),</span>
    <span class="nc">Action</span><span class="p">(</span><span class="sh">"</span><span class="s">sohbet</span><span class="sh">"</span><span class="p">,</span> <span class="p">{</span><span class="sh">"</span><span class="s">social</span><span class="sh">"</span><span class="p">:</span> <span class="mf">0.5</span><span class="p">},</span> <span class="mi">12</span><span class="p">),</span>
<span class="p">]</span>

<span class="k">def</span> <span class="nf">score</span><span class="p">(</span><span class="n">action</span><span class="p">):</span>
    <span class="n">benefit</span> <span class="o">=</span> <span class="nf">sum</span><span class="p">(</span>
        <span class="n">weights</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">*</span> <span class="n">needs</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">*</span> <span class="nf">min</span><span class="p">(</span><span class="n">needs</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="n">relief</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">relief</span> <span class="ow">in</span> <span class="n">action</span><span class="p">.</span><span class="n">relief</span><span class="p">.</span><span class="nf">items</span><span class="p">()</span>
    <span class="p">)</span>
    <span class="k">return</span> <span class="n">benefit</span> <span class="o">-</span> <span class="mf">0.002</span> <span class="o">*</span> <span class="n">action</span><span class="p">.</span><span class="n">seconds</span>

<span class="k">def</span> <span class="nf">choose</span><span class="p">(</span><span class="n">available</span><span class="p">,</span> <span class="n">current_name</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">available</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>
    <span class="n">best</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="n">available</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">score</span><span class="p">)</span>
    <span class="n">current</span> <span class="o">=</span> <span class="nf">next</span><span class="p">(</span>
        <span class="p">(</span><span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">available</span> <span class="k">if</span> <span class="n">a</span><span class="p">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">current_name</span><span class="p">),</span> <span class="bp">None</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">current</span> <span class="ow">and</span> <span class="nf">score</span><span class="p">(</span><span class="n">best</span><span class="p">)</span> <span class="o">&lt;</span> <span class="nf">score</span><span class="p">(</span><span class="n">current</span><span class="p">)</span> <span class="o">+</span> <span class="mf">0.05</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">current</span>
    <span class="k">return</span> <span class="n">best</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">choose</span><span class="p">(</span><span class="n">actions</span><span class="p">).</span><span class="n">name</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Action</code>, eylemin etkisini ve süresini taşır. <code class="language-plaintext highlighter-rouge">score</code>, ihtiyaçlarla faydayı eşleştirir; <code class="language-plaintext highlighter-rouge">choose</code> ise en yüksek puanı seçer. Örnekte yemek kazanır. Eşik sayesinde karakter, puanlar birbirine yakınken sürekli fikir değiştirmez. Bu teknik <strong>histerezis</strong> olarak bilinir. Yine de mevcut eylem geçersizleşirse korunmaz; karar motoru başka bir seçenek arar.</p>

<h2 id="mahalleye-hayat-veren-ayrıntılar">Mahalleye hayat veren ayrıntılar</h2>

<p>Puanlama tek başına yeterli değildir. Eylem adayları üretilirken nesnenin erişilebilirliği, kullanım kapasitesi ve yol bulma sonucu kontrol edilmelidir. Tuvaleti iki karakter aynı anda kullanmaya çalışıyorsa bir rezervasyon sistemi gerekir; yoksa dijital eviniz trafik kazasına döner.</p>

<p>Kişilik, ağırlıkları değiştirerek davranış çeşitliliği sağlar. Dışa dönük bir karakter sosyalliğe daha çok önem verebilir. İlişkiler, sohbetin beklenen faydasını; ruh hâli, eylem tercihlerini etkileyebilir. Bunlar rastgelelikten daha tutarlı farklılıklar üretir.</p>

<p>Son olarak aç kalma süresi, eylem değiştirme sıklığı ve nesne önündeki kuyrukları ölçün. Zaman adımını değiştirince davranışlar bozuluyorsa modeli yeniden ayarlayın. Başarılı yapay yaşam, en karmaşık algoritma değil; oyuncunun anlamlandırabildiği, tutarlı ama şaşırtıcı küçük hikâyeler üreten sistemdir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="yapay yaşam" /><category term="oyun geliştirme" /><category term="simülasyon" /><category term="yapay zeka" /><category term="utility ai" /><category term="python" /><summary type="html"><![CDATA[Bir karakter düşünün: Karnı aç, uykusu var, ama komşusuyla dedikodu yapmayı da bırakamıyor. Simülasyon oyunlarını eğlenceli kılan tam olarak bu küçük çelişkilerdir. The Sims benzeri oyunlarda karakterler, yalnızca hazır animasyonlar oynatan kuklalar değildir; ihtiyaçları, çevresel fırsatları ve karar kuralları sayesinde yaşayan bir mahalle izlenimi yaratırlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/dijital-karakterlerin-derdi-34.png" /><media:content medium="image" url="https://program.sonsuz.us/img/dijital-karakterlerin-derdi-34.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Domatesin Dijital Pasaportu: Blok Zincir ile Tarladan Sofraya İzlenebilirlik</title><link href="https://program.sonsuz.us/posts/domatesin-dijital-pasaportu-blok-zincir-ile-tarladan-sofraya-izlenebilirlik/" rel="alternate" type="text/html" title="Domatesin Dijital Pasaportu: Blok Zincir ile Tarladan Sofraya İzlenebilirlik" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/domatesin-dijital-pasaportu-blok-zincir-ile-tarladan-sofraya-izlenebilirlik</id><content type="html" xml:base="https://program.sonsuz.us/posts/domatesin-dijital-pasaportu-blok-zincir-ile-tarladan-sofraya-izlenebilirlik/"><![CDATA[<p><img src="/img/domatesin-dijital-pasaportu-50.svg" alt="domatesin-dijital-pasaportu-50" /></p>

<p>Bir domatesin yolculuğu, market rafında başlamaz. Tarlada hasat edilir, paketlenir, kamyona yüklenir ve sonunda sofranıza ulaşır. Peki ambalajdaki “yerel üretim” iddiasını nasıl doğrulayabilirsiniz? Blok zincir, bu yolculuğun kayıtlarını farklı işletmeler arasında paylaşmayı ve sonradan yapılan değişiklikleri fark etmeyi sağlayabilir. Domatese dijital pasaport çıkarmaya hazır mısınız?</p>

<p>``</p>

<h2 id="temel-mantık-birbirine-bağlanan-kayıtlar">Temel Mantık: Birbirine Bağlanan Kayıtlar</h2>

<p>İzlenebilirlik, bir ürünün kim tarafından, nerede ve ne zaman işlendiğini takip edebilmektir. Klasik sistemlerde kayıtlar çoğunlukla ayrı veritabanlarında tutulur. Çiftçinin defteriyle lojistik firmasının tablosu uyuşmadığında, gerçeği bulmak dedektiflik işine dönüşebilir.</p>

<p>Blok zincirde işlemler, ortak kurallarla doğrulanan bir deftere eklenir. Bloklar önceki blokların kriptografik özetlerine bağlanır. Basitleştirilmiş bir olay zincirini şöyle düşünebiliriz:</p>

\[h_i = H(h_{i-1} \Vert E_i)\]

<p>Burada $E_i$ yeni olay, $H$ özet fonksiyonu, $h_i$ yeni özettir. $\Vert$ verilerin birleştirilmesini gösterir. Eski kayıtta küçük bir değişiklik bile özeti değiştirir. Ancak güvenlik yalnızca bu matematikten gelmez: dijital imzalar, doğrulayıcılar ve uzlaşma mekanizması da gerekir.</p>

<h2 id="önce-ürünü-değil-partiyi-tanımlayın">Önce Ürünü Değil, Partiyi Tanımlayın</h2>

<p>Her domatese ayrı kimlik vermek genellikle pahalıdır. Bunun yerine aynı hasattan gelen ürünler bir parti numarasıyla izlenebilir: <code class="language-plaintext highlighter-rouge">DOM-2026-042</code> gibi.</p>

<p>Her olay; parti kimliği, aşama, zaman, işletme kimliği, miktar ve konum referansı taşımalıdır. Parti bölünürse yeni alt partiler oluşturulur; karıştırılırsa kaynak partiler açıkça ilişkilendirilir. Yoksa dijital pasaport, yolculuğun yarısında hafızasını kaybeder!</p>

<table>
  <thead>
    <tr>
      <th>Aşama</th>
      <th>Kaydedilen bilgi</th>
      <th>Sağladığı fayda</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Hasat</td>
      <td>Tarla, tarih, üretici</td>
      <td>Kaynağı belirleme</td>
    </tr>
    <tr>
      <td>Paketleme</td>
      <td>Parti, tesis, miktar</td>
      <td>Bölünmeleri takip etme</td>
    </tr>
    <tr>
      <td>Sevkiyat</td>
      <td>Taşıyıcı, sıcaklık özeti</td>
      <td>Soğuk zinciri denetleme</td>
    </tr>
    <tr>
      <td>Teslim</td>
      <td>Alıcı, zaman, kabul durumu</td>
      <td>Sorumluluk devrini görme</td>
    </tr>
  </tbody>
</table>

<p>Miktar kontrolü de önemlidir. Basit bir denge için $Q_g = Q_c + Q_f + Q_k$ kullanılabilir: giren miktar; çıkan ürün, fire ve kalan stok toplamına eşit olmalıdır. Böylece 120 kilogram domatesten sihirli biçimde 180 kilogram ürün çıkması işaretlenir.</p>

<h2 id="küçük-bir-kod-deneyi">Küçük Bir Kod Deneyi</h2>

<p>Aşağıdaki Node.js örneği, bir olayın önceki özete bağlanmasını gösterir. Bu, çalışan bir blok zincir değil; kayıt bağlantısının öğretici bir modelidir.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">createHash</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">node:crypto</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">stages</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Set</span><span class="p">([</span>
  <span class="dl">"</span><span class="s2">hasat</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">paketleme</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">sevkiyat</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">teslim</span><span class="dl">"</span>
<span class="p">]);</span>

<span class="kd">function</span> <span class="nf">makeRecord</span><span class="p">(</span><span class="nx">previousHash</span><span class="p">,</span> <span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">stages</span><span class="p">.</span><span class="nf">has</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">stage</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Geçersiz aşama</span><span class="dl">"</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">quantityKg</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Miktar pozitif olmalı</span><span class="dl">"</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="kd">const</span> <span class="nx">payload</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">([</span>
    <span class="nx">event</span><span class="p">.</span><span class="nx">batchId</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">stage</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">time</span><span class="p">,</span>
    <span class="nx">event</span><span class="p">.</span><span class="nx">actorId</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">quantityKg</span>
  <span class="p">]);</span>
  <span class="kd">const</span> <span class="nx">hash</span> <span class="o">=</span> <span class="nf">createHash</span><span class="p">(</span><span class="dl">"</span><span class="s2">sha256</span><span class="dl">"</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="nx">previousHash</span> <span class="o">+</span> <span class="nx">payload</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">digest</span><span class="p">(</span><span class="dl">"</span><span class="s2">hex</span><span class="dl">"</span><span class="p">);</span>

  <span class="k">return</span> <span class="p">{</span> <span class="nx">previousHash</span><span class="p">,</span> <span class="nx">payload</span><span class="p">,</span> <span class="nx">hash</span> <span class="p">};</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">harvest</span> <span class="o">=</span> <span class="nf">makeRecord</span><span class="p">(</span><span class="dl">"</span><span class="s2">0</span><span class="dl">"</span><span class="p">.</span><span class="nf">repeat</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="p">{</span>
  <span class="na">batchId</span><span class="p">:</span> <span class="dl">"</span><span class="s2">DOM-2026-042</span><span class="dl">"</span><span class="p">,</span> <span class="na">stage</span><span class="p">:</span> <span class="dl">"</span><span class="s2">hasat</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">time</span><span class="p">:</span> <span class="dl">"</span><span class="s2">2026-10-06T08:00:00Z</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">actorId</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ciftci-17</span><span class="dl">"</span><span class="p">,</span> <span class="na">quantityKg</span><span class="p">:</span> <span class="mi">120</span>
<span class="p">});</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">harvest</span><span class="p">.</span><span class="nx">hash</span><span class="p">);</span>
</code></pre></div></div>

<p>Sabit alan sırası, aynı verinin aynı özeti üretmesine yardımcı olur. Sonraki olayda <code class="language-plaintext highlighter-rouge">previousHash</code> olarak <code class="language-plaintext highlighter-rouge">harvest.hash</code> kullanılır. Gerçek uygulamada şema doğrulaması, yetkilendirme ve imza kontrolü eklenmelidir. Tek kişinin yönettiği bu örnek zincir baştan hesaplanabilir; onu ortak uzlaşmayla korunan ağla karıştırmayın.</p>

<h2 id="değiştirilemezlik-doğruluk-demek-değildir">Değiştirilemezlik, Doğruluk Demek Değildir</h2>

<p>Sensör yanlış ölçüyorsa blok zincir yanlış sıcaklığı sadakatle saklar. Buna fiziksel dünya ile dijital kayıt arasındaki güven problemi diyebiliriz. Kalibrasyon, mühürlü ambalaj, denetim ve güvenilir veri girişleri hâlâ gereklidir.</p>

<p>“Değiştirilemez” ifadesi de koşulludur: geçmişin değiştirilmesi ağın güvenlik varsayımları altında zorlaştırılır. Hatalı kayıt silinmek yerine, önceki olaya referans veren düzeltme işlemiyle tamamlanır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dikkat noktası</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Merkezi veritabanı</td>
      <td>Basit, hızlı, ekonomik</td>
      <td>Yöneticiye güven gerekir</td>
    </tr>
    <tr>
      <td>İzinli blok zincir</td>
      <td>Kurumlar arası ortak doğrulama</td>
      <td>Katılımcı yönetimi gerekir</td>
    </tr>
    <tr>
      <td>Açık blok zincir</td>
      <td>Geniş doğrulanabilirlik</td>
      <td>Ücret ve gizlilik değerlendirilir</td>
    </tr>
  </tbody>
</table>

<h2 id="pilot-projeyi-nasıl-kurarsınız">Pilot Projeyi Nasıl Kurarsınız?</h2>

<p>Bir üretici, paketleme tesisi ve marketle başlayın. Belgeleri ve ayrıntılı sensör verilerini erişim kontrollü depoda tutun; zincire özetlerini ve gerekli referansları yazın. Özet, belgenin değiştiğini gösterebilir ama belgenin erişilebilirliğini garanti etmez.</p>

<p>Ambalajdaki QR kod, tüketiciyi izlenebilirlik ekranına götürsün. Ticari sırları herkese açmadan köken ve aşamaları gösterin. Başarıyı işlem sayısıyla değil; geri çağırma süresi, kayıt eksikliği ve doğrulama maliyetiyle ölçün. Amaç domatesi teknolojiyle süslemek değil, sorun çıktığında doğru partiyi hızla bulmaktır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="blok zincir" /><category term="tarım" /><category term="izlenebilirlik" /><category term="gıda güvenliği" /><category term="javascript" /><category term="tedarik zinciri" /><summary type="html"><![CDATA[Bir domatesin yolculuğu, market rafında başlamaz. Tarlada hasat edilir, paketlenir, kamyona yüklenir ve sonunda sofranıza ulaşır. Peki ambalajdaki “yerel üretim” iddiasını nasıl doğrulayabilirsiniz? Blok zincir, bu yolculuğun kayıtlarını farklı işletmeler arasında paylaşmayı ve sonradan yapılan değişiklikleri fark etmeyi sağlayabilir. Domatese dijital pasaport çıkarmaya hazır mısınız?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/domatesin-dijital-pasaportu-50.png" /><media:content medium="image" url="https://program.sonsuz.us/img/domatesin-dijital-pasaportu-50.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ev Sessizleşince: Hareket Sensörleriyle Günlük Rutinlerdeki Sapmaları Yakalamak</title><link href="https://program.sonsuz.us/posts/ev-sessizlesince-hareket-sensorleriyle-gunluk-rutinlerdeki-sapmalari-yakalamak/" rel="alternate" type="text/html" title="Ev Sessizleşince: Hareket Sensörleriyle Günlük Rutinlerdeki Sapmaları Yakalamak" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ev-sessizlesince-hareket-sensorleriyle-gunluk-rutinlerdeki-sapmalari-yakalamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/ev-sessizlesince-hareket-sensorleriyle-gunluk-rutinlerdeki-sapmalari-yakalamak/"><![CDATA[<p><img src="/img/ev-sessizlesince-hareket-72.svg" alt="ev-sessizlesince-hareket-72" /></p>

<p>Sabah mutfakta başlayan hareketlilik, öğleden sonra salona taşınan sakinlik… Evlerin de kendine özgü bir ritmi vardır. Hareket sensörleri, bu ritimdeki beklenmedik değişiklikleri görünür kılabilir. Ama amaç eve dijital bir Sherlock yerleştirmek değil; yaşlı veya yalnız yaşayan bireylerin bağımsızlığını korurken, gerektiğinde iletişim kurulmasını destekleyen, mahremiyete saygılı bir yardımcı geliştirmektir.
``</p>

<h2 id="sensör-gerçekten-neyi-bilir">Sensör gerçekten neyi bilir?</h2>

<p>Yaygın PIR sensörleri, görüş alanlarındaki kızılötesi değişimlerden hareket çıkarır. Birinin kim olduğunu, ne yaptığını veya sağlık durumunu doğrudan söylemezler. Dolayısıyla “hareket yok” ile “kişi tehlikede” aynı anlama gelmez: Uyku, dışarı çıkma, kitap okuma veya bağlantı arızası benzer kayıtlar oluşturabilir.</p>

<p>Temel veri akışı şöyledir: Sensör olayı, zaman damgası ve oda bilgisi yerel bir ağ geçidine ulaşır; ardından analiz için özetlenir. Saatlerin eşitlenmesi ve yinelenen kayıtların temizlenmesi önemlidir. Olay kaydı göndermeyen cihazın çalıştığını anlayabilmek için ayrıca düzenli durum mesajları gerekir. Aksi hâlde arızalı sensör, sessiz bir ev gibi görünür.</p>

<h2 id="ham-olaylardan-anlamlı-özelliklere">Ham olaylardan anlamlı özelliklere</h2>

<p>Sensörün yeniden tetikleme süresi, olay sayısını etkiler. Bu nedenle yalnızca tetikleme sayısını karşılaştırmak yanıltıcıdır. Daha dengeli bir özellik, otuz dakikalık pencerede hareket görülen farklı dakikaların sayısıdır. Bütün odaların kayıtları birleştirilir; aynı dakika iki odada hareket varsa toplamda bir kez sayılır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Ne anlatır?</th>
      <th>Tek başına neden yetmez?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Hareketli dakika</td>
      <td>Genel etkinlik düzeyi</td>
      <td>Dışarı çıkmak da azaltır</td>
    </tr>
    <tr>
      <td>Hareketsizlik süresi</td>
      <td>Uzun sessizlik dönemleri</td>
      <td>Uyku sırasında normaldir</td>
    </tr>
    <tr>
      <td>Odalar arası geçiş</td>
      <td>Ev içindeki hareketlilik</td>
      <td>Misafirler örüntüyü değiştirir</td>
    </tr>
    <tr>
      <td>Cihaz durum mesajı</td>
      <td>Veri akışının sağlığı</td>
      <td>İnsan davranışını ölçmez</td>
    </tr>
  </tbody>
</table>

<p>İlk üç veya dört hafta, kişinin kendi referansını oluşturmak için kullanılabilir. Hafta içi ve hafta sonu ayrı değerlendirilmelidir. Karşılaştırma başka insanların ortalamasıyla değil, aynı kişinin benzer zaman dilimlerindeki geçmişiyle yapılır.</p>

<h2 id="normalden-uzaklığı-ölçmek">Normalden uzaklığı ölçmek</h2>

<p>Başlangıç için karmaşık bir sinir ağı şart değildir. Medyan, sıra dışı günlerden ortalamaya göre daha az etkilenir. Yayılımı ölçen medyan mutlak sapma ise $MAD = \operatorname{medyan}(\vert x_i-m\vert )$ şeklinde hesaplanır; burada $m$, geçmiş değerlerin medyanıdır.</p>

<p>Azalan etkinlik için kullanılabilecek sağlamlaştırılmış skor:</p>

\[z_t = \frac{m-x_t}{\max(1,\;1.4826\cdot MAD)}\]

<p>Burada $x_t$, güncel penceredeki hareketli dakika sayısıdır. Paydadaki 1, bir dakikalık alt sınırdır; geçmiş değerler aynı olduğunda sıfıra bölmeyi önler. Büyük pozitif skor, beklenenden düşük etkinlik gösterir. Örneğin medyan 18, MAD 3 ve güncel değer 2 olduğunda skor yaklaşık 3,6 olur. Ancak 3 gibi bir eşik yalnızca başlangıç tercihidir; klinik olarak doğrulanmış bir sınır değildir.</p>

<h2 id="python-ile-aday-sapmaları-çıkaralım">Python ile aday sapmaları çıkaralım</h2>

<p>Aşağıdaki kod, geçmiş özetlerden profil oluşturur ve güncel pencereleri karşılaştırır. <code class="language-plaintext highlighter-rouge">dilim</code>, gün içindeki otuz dakikalık zaman aralığını temsil eder. Güncel kayıtların geçmiş eğitim verisine katılmaması önemlidir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="n">anahtar</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">gun_tipi</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">dilim</span><span class="sh">'</span><span class="p">]</span>
<span class="n">grup</span> <span class="o">=</span> <span class="n">gecmis</span><span class="p">.</span><span class="nf">groupby</span><span class="p">(</span><span class="n">anahtar</span><span class="p">)[</span><span class="sh">'</span><span class="s">aktif_dakika</span><span class="sh">'</span><span class="p">]</span>

<span class="n">profil</span> <span class="o">=</span> <span class="n">grup</span><span class="p">.</span><span class="nf">agg</span><span class="p">(</span><span class="n">merkez</span><span class="o">=</span><span class="sh">'</span><span class="s">median</span><span class="sh">'</span><span class="p">,</span> <span class="n">ornek</span><span class="o">=</span><span class="sh">'</span><span class="s">count</span><span class="sh">'</span><span class="p">)</span>
<span class="n">profil</span><span class="p">[</span><span class="sh">'</span><span class="s">mad</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">grup</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span>
    <span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="p">(</span><span class="n">s</span> <span class="o">-</span> <span class="n">s</span><span class="p">.</span><span class="nf">median</span><span class="p">()).</span><span class="nf">abs</span><span class="p">().</span><span class="nf">median</span><span class="p">()</span>
<span class="p">)</span>
<span class="n">profil</span><span class="p">[</span><span class="sh">'</span><span class="s">olcek</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="mf">1.4826</span> <span class="o">*</span> <span class="n">profil</span><span class="p">[</span><span class="sh">'</span><span class="s">mad</span><span class="sh">'</span><span class="p">]).</span><span class="nf">clip</span><span class="p">(</span><span class="n">lower</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>

<span class="n">sonuc</span> <span class="o">=</span> <span class="n">guncel</span><span class="p">.</span><span class="nf">merge</span><span class="p">(</span>
    <span class="n">profil</span><span class="p">.</span><span class="nf">reset_index</span><span class="p">(),</span>
    <span class="n">on</span><span class="o">=</span><span class="n">anahtar</span><span class="p">,</span>
    <span class="n">how</span><span class="o">=</span><span class="sh">'</span><span class="s">left</span><span class="sh">'</span><span class="p">,</span>
    <span class="n">validate</span><span class="o">=</span><span class="sh">'</span><span class="s">many_to_one</span><span class="sh">'</span>
<span class="p">)</span>
<span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">puan</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
    <span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">merkez</span><span class="sh">'</span><span class="p">]</span> <span class="o">-</span> <span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">aktif_dakika</span><span class="sh">'</span><span class="p">]</span>
<span class="p">)</span> <span class="o">/</span> <span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">olcek</span><span class="sh">'</span><span class="p">]</span>

<span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">aday</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
    <span class="p">(</span><span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">puan</span><span class="sh">'</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">)</span>
    <span class="o">&amp;</span> <span class="p">(</span><span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">ornek</span><span class="sh">'</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">6</span><span class="p">)</span>
    <span class="o">&amp;</span> <span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">sensorler_cevrimici</span><span class="sh">'</span><span class="p">]</span>
    <span class="o">&amp;</span> <span class="n">sonuc</span><span class="p">[</span><span class="sh">'</span><span class="s">evde_olmasi_bekleniyor</span><span class="sh">'</span><span class="p">]</span>
<span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">gecmis</code> ve <code class="language-plaintext highlighter-rouge">guncel</code>, önceden hazırlanmış DataFrame tablolarıdır. Çıktı acil durum kararı değil, inceleme adayıdır. Evde bulunma beklentisi, yalnızca hareket yokluğundan çıkarılmamalı; kişinin belirttiği program gibi izinli bağlamlarla desteklenmelidir.</p>

<h2 id="alarm-değil-kontrollü-iletişim">Alarm değil, kontrollü iletişim</h2>

<p>Tek pencere yerine ardışık pencerelerdeki sapmalar değerlendirilebilir. Ancak beklemek acil durumları geciktirebileceğinden, bu sistem tıbbi alarmın yerine geçmez. Bildirim politikası kişiyle birlikte belirlenmeli; önce nazik bir kontrol mesajı, gerekiyorsa yetkilendirilmiş yakına bildirim düşünülmelidir.</p>

<p>Başarıyı yalnızca doğrulukla ölçmeyin. Haftalık yanlış bildirim sayısı, tespit gecikmesi ve gözden kaçan olaylar da izlenmelidir. Tatiller veya kalıcı rutin değişiklikleri sonrasında profil kontrollü biçimde güncellenmelidir.</p>

<p>Son olarak, açık rıza, bildirimleri durdurabilme, sınırlı saklama süresi ve erişim kontrolü tasarımın temelidir. Mümkünse ham verileri evde tutup yalnızca gerekli özetleri paylaşın. İyi sistem, her sessizliği felaket sayan değil; belirsizliğini kabul edip insan iletişimini destekleyen sistemdir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="iot" /><category term="python" /><category term="anomali tespiti" /><category term="hareket sensörleri" /><category term="veri analizi" /><category term="yaşlı bakımı" /><summary type="html"><![CDATA[Sabah mutfakta başlayan hareketlilik, öğleden sonra salona taşınan sakinlik… Evlerin de kendine özgü bir ritmi vardır. Hareket sensörleri, bu ritimdeki beklenmedik değişiklikleri görünür kılabilir. Ama amaç eve dijital bir Sherlock yerleştirmek değil; yaşlı veya yalnız yaşayan bireylerin bağımsızlığını korurken, gerektiğinde iletişim kurulmasını destekleyen, mahremiyete saygılı bir yardımcı geliştirmektir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/ev-sessizlesince-hareket-72.png" /><media:content medium="image" url="https://program.sonsuz.us/img/ev-sessizlesince-hareket-72.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Fırlatmadan Önce Dijital Prova: Roket Yazılımında Hardware-in-the-Loop</title><link href="https://program.sonsuz.us/posts/firlatmadan-once-dijital-prova-roket-yaziliminda-hardware-in-the-loop/" rel="alternate" type="text/html" title="Fırlatmadan Önce Dijital Prova: Roket Yazılımında Hardware-in-the-Loop" /><published>2026-10-31T00:00:00+00:00</published><updated>2026-10-31T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/firlatmadan-once-dijital-prova-roket-yaziliminda-hardware-in-the-loop</id><content type="html" xml:base="https://program.sonsuz.us/posts/firlatmadan-once-dijital-prova-roket-yaziliminda-hardware-in-the-loop/"><![CDATA[<p>Bir roketin uçuş bilgisayarına “Önce deneyelim, hata çıkarsa yeniden başlatırız” demek pek iyi bir mühendislik stratejisi değildir. Gerçek fırlatma pahalıdır, tekrarı zordur ve hata toleransı düşüktür. Hardware-in-the-Loop, yani HIL, gerçek elektronik donanımı sanal bir araçla buluşturarak yazılıma güvenli bir prova sahnesi sunar.</p>

<p><img src="/img/firlatmadan-once-dijital-90.svg" alt="firlatmadan-once-dijital-90" /></p>

<p>``</p>

<h2 id="hil-tam-olarak-neyi-test-eder">HIL tam olarak neyi test eder?</h2>

<p>HIL düzeninde uçuş bilgisayarı ve üzerinde çalışan yazılım gerçektir; aracın hareketi, çevresi ve bazı fiziksel bileşenleri ise modellerle temsil edilir. Simülatör, bilgisayara sensörlerden geliyormuş gibi veriler gönderir. Bilgisayarın ürettiği çıkışlar da modele geri aktarılır. Böylece tek yönlü veri oynatımından farklı olarak kapalı bir geri besleme döngüsü oluşur.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Gerçek olan</th>
      <th>Temel katkısı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SIL</td>
      <td>Yazılım mantığı</td>
      <td>Algoritmaları hızlı sınamak</td>
    </tr>
    <tr>
      <td>HIL</td>
      <td>İşlemci, yazılım ve seçilen arayüzler</td>
      <td>Donanım-yazılım etkileşimini sınamak</td>
    </tr>
    <tr>
      <td>Fiziksel sistem testi</td>
      <td>Test edilen fiziksel bileşenler</td>
      <td>Modelin kapsamadığı etkileri gözlemek</td>
    </tr>
  </tbody>
</table>

<p>SIL, Software-in-the-Loop anlamına gelir. Burada hedef donanım yerine bilgisayar ortamı kullanılır. HIL ise işlemci yükü, iletişim gecikmesi ve sürücü davranışı gibi “masada çalışıyordu!” sürprizlerini görünür kılar. İkisi rakip değil, birbirini tamamlayan test katmanlarıdır.</p>

<h2 id="teorik-temel-model-ve-zaman-aynı-sahnede">Teorik temel: Model ve zaman aynı sahnede</h2>

<p>Bir simülasyon modeli genel biçimde $x_{k+1}=f(x_k,u_k,w_k)$ ile gösterilebilir. Burada $x_k$ sistemin durumunu, $u_k$ bilgisayardan gelen çıkışları, $w_k$ ise çevresel etkileri veya bozucuları temsil eder. Sensör modeli de bu durumdan ölçüm üretir; ölçümlere gecikme, gürültü ve çözünürlük sınırları eklenebilir.</p>

<p>HIL için doğru değer üretmek kadar doğru zamanda üretmek de önemlidir. Sabit adımlı bir döngüde kabaca şu bütçe korunmalıdır:</p>

\[T_{model}+T_{comm}+T_{io}&lt;\Delta t\]

<p>Yani model hesaplama, haberleşme ve giriş-çıkış işlemleri ayrılan zaman adımına sığmalıdır. Ancak ortalama süre yeterli değildir: En kötü gecikme ve zamanlama değişkenliği de izlenmelidir. Simülasyon sürekli yetişemiyorsa test, gerçek donanım davranışı hakkında yanıltıcı sonuçlar verebilir.</p>

<h2 id="sanal-araç-gerçek-bağlantılar">Sanal araç, gerçek bağlantılar</h2>

<p>Tipik düzenek; gerçek uçuş bilgisayarı, gerçek zamanlı simülatör, arayüz donanımı ve kayıt sisteminden oluşur. Arayüz katmanı dijital mesajları veya analog sinyalleri hedef bilgisayarın beklediği biçime dönüştürür. Paket içeriği kadar elektriksel seviyeler ve zaman damgaları da önemlidir.</p>

<p>Tehlikeli eyleyiciler yerine izole edilmiş yükler veya güvenli benzetimler kullanılmalıdır. Amaç motor çalıştırmak değil, bilgisayarın kararlarını gözlemlemektir. Hangi bileşenlerin gerçek, hangilerinin benzetim olduğu test raporunda açıkça belirtilmelidir.</p>

<h2 id="hataları-davet-edin-sonuçları-ölçün">Hataları davet edin, sonuçları ölçün</h2>

<p>Başarılı senaryonun yanında arızalı senaryolar da gerekir. Her arıza için beklenen davranış önceden tanımlanmalıdır; aksi hâlde renkli grafikler yalnızca pahalı bir ekran koruyucuya dönüşür.</p>

<table>
  <thead>
    <tr>
      <th>Enjekte edilen durum</th>
      <th>Kontrol edilen davranış</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Geçersiz sensör verisi</td>
      <td>Veri kalitesi bilgisinin işlenmesi</td>
    </tr>
    <tr>
      <td>Gecikmiş mesaj</td>
      <td>Zaman aşımı ve hata kaydı</td>
    </tr>
    <tr>
      <td>Tekrarlanan paket</td>
      <td>Eski verinin ayırt edilmesi</td>
    </tr>
    <tr>
      <td>Yoğun iletişim trafiği</td>
      <td>Görev sürelerinin korunması</td>
    </tr>
  </tbody>
</table>

<p>Kabul ölçütleri; tepki süresi, kayıp paket sayısı ve gereksinimle eşleştirilmiş durum geçişleri olabilir. Test girdileri, yazılım sürümü ve model parametreleri kaydedilirse aynı hata yeniden üretilebilir. Rastgele senaryolarda kullanılan tohum değeri de saklanmalıdır.</p>

<h2 id="python-ile-kavramsal-bir-test-akışı">Python ile kavramsal bir test akışı</h2>

<p>Aşağıdaki örnekte <code class="language-plaintext highlighter-rouge">bench</code> gerçek karta bağlanan test arayüzünü, <code class="language-plaintext highlighter-rouge">plant</code> ise fiziksel sistem modelini temsil eder. Bunlar hazır kütüphaneler değildir; kullanılan düzeneğe göre uygulanması gereken soyut arayüzlerdir. Örnek, kısa süreli sıcaklık verisi geçersizliği enjekte eder.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">time</span> <span class="kn">import</span> <span class="n">monotonic</span><span class="p">,</span> <span class="n">sleep</span>


<span class="k">def</span> <span class="nf">run_case</span><span class="p">(</span><span class="n">bench</span><span class="p">,</span> <span class="n">plant</span><span class="p">,</span> <span class="n">steps</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">dt</span><span class="o">=</span><span class="mf">0.01</span><span class="p">):</span>
    <span class="n">deadline</span> <span class="o">=</span> <span class="nf">monotonic</span><span class="p">()</span>
    <span class="n">trace</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">steps</span><span class="p">):</span>
        <span class="n">t</span> <span class="o">=</span> <span class="n">k</span> <span class="o">*</span> <span class="n">dt</span>
        <span class="n">sensors</span> <span class="o">=</span> <span class="nf">dict</span><span class="p">(</span><span class="n">plant</span><span class="p">.</span><span class="nf">sample</span><span class="p">())</span>
        <span class="k">if</span> <span class="mf">0.5</span> <span class="o">&lt;=</span> <span class="n">t</span> <span class="o">&lt;</span> <span class="mf">0.6</span><span class="p">:</span>
            <span class="n">sensors</span><span class="p">[</span><span class="sh">"</span><span class="s">temperature_valid</span><span class="sh">"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">False</span>

        <span class="n">bench</span><span class="p">.</span><span class="nf">send_sensors</span><span class="p">(</span><span class="n">sensors</span><span class="p">,</span> <span class="n">timestamp</span><span class="o">=</span><span class="n">t</span><span class="p">)</span>
        <span class="n">outputs</span> <span class="o">=</span> <span class="n">bench</span><span class="p">.</span><span class="nf">read_outputs</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="n">dt</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span>
        <span class="n">plant</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span> <span class="n">dt</span><span class="p">)</span>
        <span class="n">trace</span><span class="p">.</span><span class="nf">append</span><span class="p">((</span><span class="n">t</span><span class="p">,</span> <span class="n">outputs</span><span class="p">))</span>

        <span class="n">deadline</span> <span class="o">+=</span> <span class="n">dt</span>
        <span class="n">remaining</span> <span class="o">=</span> <span class="n">deadline</span> <span class="o">-</span> <span class="nf">monotonic</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">remaining</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">raise</span> <span class="nc">RuntimeError</span><span class="p">(</span><span class="sh">"</span><span class="s">Zaman bütçesi aşıldı</span><span class="sh">"</span><span class="p">)</span>
        <span class="nf">sleep</span><span class="p">(</span><span class="n">remaining</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">trace</span>
</code></pre></div></div>

<p>Döngü, sensör verisini gönderir, kartın çıkışını toplar ve modeli ilerletir. Birikimli son tarih kullanılması zaman kaymasını azaltır. Bununla birlikte standart Python ve <code class="language-plaintext highlighter-rouge">sleep</code>, kesin gerçek zaman garantisi vermez; örnek üretim düzeneği değil, akışı açıklayan bir iskelettir. Gerçek testte kayıtların ayrıca otomatik doğrulayıcılardan geçirilmesi gerekir.</p>

<h2 id="hil-güçlüdür-ama-sihir-değildir">HIL güçlüdür, ama sihir değildir</h2>

<p>Model yanlışsa test kusursuz görünse bile sonuç yanlış olabilir. Bu nedenle modeller deneysel verilerle doğrulanmalı, belirsizlikler belgelenmeli ve farklı koşullar taranmalıdır. HIL; titreşim, elektromanyetik uyumluluk veya gerçek fiziksel sistem testlerinin yerine geçmez. En büyük kazancı, pahalı denemelerden önce hataları tekrarlanabilir biçimde yakalamaktır: Roketi değil, önce varsayımlarımızı havaya uçururuz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="roket-yazılımı" /><category term="hardware-in-the-loop" /><category term="simülasyon" /><category term="gömülü-sistemler" /><category term="yazılım-testi" /><summary type="html"><![CDATA[Bir roketin uçuş bilgisayarına “Önce deneyelim, hata çıkarsa yeniden başlatırız” demek pek iyi bir mühendislik stratejisi değildir. Gerçek fırlatma pahalıdır, tekrarı zordur ve hata toleransı düşüktür. Hardware-in-the-Loop, yani HIL, gerçek elektronik donanımı sanal bir araçla buluşturarak yazılıma güvenli bir prova sahnesi sunar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/firlatmadan-once-dijital-90.png" /><media:content medium="image" url="https://program.sonsuz.us/img/firlatmadan-once-dijital-90.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>