<?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-09-16T07:13:41+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">A* ile Robotik Yol Planlama: Engellerden Kaçan En Kısa Rotayı Bulmak</title><link href="https://program.sonsuz.us/posts/a-ile-robotik-yol-planlama-engellerden-kacan-en-kisa-rotayi-bulmak/" rel="alternate" type="text/html" title="A* ile Robotik Yol Planlama: Engellerden Kaçan En Kısa Rotayı Bulmak" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/a-ile-robotik-yol-planlama-engellerden-kacan-en-kisa-rotayi-bulmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/a-ile-robotik-yol-planlama-engellerden-kacan-en-kisa-rotayi-bulmak/"><![CDATA[<p>Bir robotun başlangıç noktasından hedefe gitmesi kolay görünebilir; ta ki odanın ortasına sandalye, kutu ve duvarlar yerleştirene kadar! Robotik yol planlamanın amacı, hareketli sistemi engellere çarptırmadan hedefe ulaştıracak mümkün olan en düşük maliyetli rotayı bulmaktır. A* algoritması, gerçek maliyet ile hedefe yönelik tahmini birleştirerek bu işi hem verimli hem de anlaşılır biçimde yapar.</p>

<p>``</p>

<h2 id="a-algoritmasının-temel-fikri">A* algoritmasının temel fikri</h2>

<p>A*, harita üzerindeki her aday düğüm için üç değer kullanır:</p>

\[f(n) = g(n) + h(n)\]

<p>Burada $g(n)$, başlangıçtan mevcut düğüme kadar ödenen gerçek maliyettir. $h(n)$ ise düğümden hedefe kalan mesafeye ilişkin sezgisel tahmindir. Algoritma, toplam tahmini maliyeti $f(n)$ en küçük olan düğümü önce inceler.</p>

<p>Bunu bir navigasyon uygulaması gibi düşünebiliriz: $g(n)$ şimdiye kadar kullandığımız yakıtı, $h(n)$ ise hedefe ulaşmak için harcayacağımız tahmini yakıtı temsil eder. Yalnızca geçmişe bakmak aramayı yavaşlatır; yalnızca tahmine güvenmek ise kötü rotalara yol açabilir. A*, ikisini dengeler.</p>

<table>
  <thead>
    <tr>
      <th>Algoritma</th>
      <th style="text-align: right">Gerçek maliyet</th>
      <th style="text-align: right">Sezgisel tahmin</th>
      <th>Tipik davranış</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Dijkstra</td>
      <td style="text-align: right">Var</td>
      <td style="text-align: right">Yok</td>
      <td>Garantili fakat geniş arama yapar</td>
    </tr>
    <tr>
      <td>Greedy Best-First</td>
      <td style="text-align: right">Yok</td>
      <td style="text-align: right">Var</td>
      <td>Hızlı olabilir, en kısa yolu garanti etmez</td>
    </tr>
    <tr>
      <td>A*</td>
      <td style="text-align: right">Var</td>
      <td style="text-align: right">Var</td>
      <td>Doğru sezgiyle hızlı ve optimaldir</td>
    </tr>
  </tbody>
</table>

<h2 id="izgara-haritası-ve-sezgisel-fonksiyon">Izgara haritası ve sezgisel fonksiyon</h2>

<p>Robotun çevresi çoğunlukla hücrelerden oluşan bir maliyet haritasına dönüştürülür. Boş hücreler geçilebilir, dolu hücreler engeldir. Robot yalnızca yatay ve dikey hareket ediyorsa Manhattan uzaklığı uygundur:</p>

\[h(n) = \vert x_n-x_g\vert  + \vert y_n-y_g\vert\]

<p>Çapraz hareket serbestse Öklid uzaklığı kullanılabilir:</p>

\[h(n) = \sqrt{(x_n-x_g)^2 + (y_n-y_g)^2}\]

<p>En kısa yol garantisi için sezgisel fonksiyon gerçek kalan maliyeti abartmamalıdır. Bu özelliğe <strong>kabul edilebilirlik</strong> denir.</p>

<h2 id="python-ile-basit-a-uygulaması">Python ile basit A* uygulaması</h2>

<p>Aşağıdaki kod, sıfırların boş alanı ve birlerin engelleri gösterdiği bir ızgarada dört yönlü rota üretir:</p>

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

<span class="k">def</span> <span class="nf">astar</span><span class="p">(</span><span class="n">grid</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">goal</span><span class="p">):</span>
    <span class="n">directions</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)]</span>
    <span class="n">open_set</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="n">start</span><span class="p">)]</span>
    <span class="n">came_from</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="n">g_cost</span> <span class="o">=</span> <span class="p">{</span><span class="n">start</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>

    <span class="k">def</span> <span class="nf">heuristic</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
        <span class="k">return</span> <span class="nf">abs</span><span class="p">(</span><span class="n">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">goal</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="nf">abs</span><span class="p">(</span><span class="n">node</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">goal</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>

    <span class="k">while</span> <span class="n">open_set</span><span class="p">:</span>
        <span class="n">_</span><span class="p">,</span> <span class="n">current</span> <span class="o">=</span> <span class="n">heapq</span><span class="p">.</span><span class="nf">heappop</span><span class="p">(</span><span class="n">open_set</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">current</span> <span class="o">==</span> <span class="n">goal</span><span class="p">:</span>
            <span class="n">path</span> <span class="o">=</span> <span class="p">[</span><span class="n">current</span><span class="p">]</span>
            <span class="k">while</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">came_from</span><span class="p">:</span>
                <span class="n">current</span> <span class="o">=</span> <span class="n">came_from</span><span class="p">[</span><span class="n">current</span><span class="p">]</span>
                <span class="n">path</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">path</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>

        <span class="k">for</span> <span class="n">dx</span><span class="p">,</span> <span class="n">dy</span> <span class="ow">in</span> <span class="n">directions</span><span class="p">:</span>
            <span class="n">neighbor</span> <span class="o">=</span> <span class="p">(</span><span class="n">current</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">dx</span><span class="p">,</span> <span class="n">current</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">dy</span><span class="p">)</span>
            <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">neighbor</span>

            <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="nf">len</span><span class="p">(</span><span class="n">grid</span><span class="p">)</span> <span class="ow">and</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="nf">len</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="mi">0</span><span class="p">])):</span>
                <span class="k">continue</span>
            <span class="k">if</span> <span class="n">grid</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="o">==</span> <span class="mi">1</span><span class="p">:</span>
                <span class="k">continue</span>

            <span class="n">candidate_cost</span> <span class="o">=</span> <span class="n">g_cost</span><span class="p">[</span><span class="n">current</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
            <span class="k">if</span> <span class="n">candidate_cost</span> <span class="o">&lt;</span> <span class="n">g_cost</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">neighbor</span><span class="p">,</span> <span class="nf">float</span><span class="p">(</span><span class="sh">"</span><span class="s">inf</span><span class="sh">"</span><span class="p">)):</span>
                <span class="n">came_from</span><span class="p">[</span><span class="n">neighbor</span><span class="p">]</span> <span class="o">=</span> <span class="n">current</span>
                <span class="n">g_cost</span><span class="p">[</span><span class="n">neighbor</span><span class="p">]</span> <span class="o">=</span> <span class="n">candidate_cost</span>
                <span class="n">f_cost</span> <span class="o">=</span> <span class="n">candidate_cost</span> <span class="o">+</span> <span class="nf">heuristic</span><span class="p">(</span><span class="n">neighbor</span><span class="p">)</span>
                <span class="n">heapq</span><span class="p">.</span><span class="nf">heappush</span><span class="p">(</span><span class="n">open_set</span><span class="p">,</span> <span class="p">(</span><span class="n">f_cost</span><span class="p">,</span> <span class="n">neighbor</span><span class="p">))</span>

    <span class="k">return</span> <span class="bp">None</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">open_set</code>, henüz değerlendirilecek hücreleri öncelik sırasıyla tutar. <code class="language-plaintext highlighter-rouge">came_from</code> ise hedef bulunduğunda geriye doğru ilerleyerek rotayı yeniden oluşturur. Engel veya harita sınırı kontrolü sayesinde robot geçersiz hücrelere girmez.</p>

<h2 id="gerçek-robotlarda-dikkat-edilmesi-gerekenler">Gerçek robotlarda dikkat edilmesi gerekenler</h2>

<p>Izgara üzerindeki robot tek bir nokta değildir; fiziksel genişliği vardır. Bu nedenle engeller, robot yarıçapı ve güvenlik payı kadar şişirilmelidir. Aksi hâlde hesaplanan rota matematiksel olarak geçerli olsa bile robot duvara sürtebilir.</p>

<table>
  <thead>
    <tr>
      <th>Sorun</th>
      <th>Pratik çözüm</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Robotun fiziksel boyutu</td>
      <td>Engel şişirme</td>
    </tr>
    <tr>
      <td>Keskin dönüşler</td>
      <td>Rota yumuşatma</td>
    </tr>
    <tr>
      <td>Hareketli engeller</td>
      <td>Haritayı yenileyip tekrar planlama</td>
    </tr>
    <tr>
      <td>Dar alanlarda risk</td>
      <td>Hücrelere ek maliyet verme</td>
    </tr>
  </tbody>
</table>

<p>A* statik haritalarda güçlü bir başlangıçtır. Sensörlerden gelen güncel veriler, maliyet haritası ve hareket denetleyicisiyle birleştirildiğinde robot yalnızca kısa değil, güvenli ve uygulanabilir bir rota da izleyebilir. Böylece “duvara çarpmadan hedefe ulaşma” problemi, düzenli bir maliyet hesabına dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="a-star" /><category term="robotik" /><category term="yol-planlama" /><category term="algoritma" /><category term="python" /><category term="yapay-zeka" /><summary type="html"><![CDATA[Bir robotun başlangıç noktasından hedefe gitmesi kolay görünebilir; ta ki odanın ortasına sandalye, kutu ve duvarlar yerleştirene kadar! Robotik yol planlamanın amacı, hareketli sistemi engellere çarptırmadan hedefe ulaştıracak mümkün olan en düşük maliyetli rotayı bulmaktır. A* algoritması, gerçek maliyet ile hedefe yönelik tahmini birleştirerek bu işi hem verimli hem de anlaşılır biçimde yapar.]]></summary></entry><entry><title type="html">Drone Uçuş Kontrolcüsü Mantığı: PID’den Otonom Rotaya</title><link href="https://program.sonsuz.us/posts/drone-ucus-kontrolcusu-mantigi-pidden-otonom-rotaya/" rel="alternate" type="text/html" title="Drone Uçuş Kontrolcüsü Mantığı: PID’den Otonom Rotaya" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/drone-ucus-kontrolcusu-mantigi-pidden-otonom-rotaya</id><content type="html" xml:base="https://program.sonsuz.us/posts/drone-ucus-kontrolcusu-mantigi-pidden-otonom-rotaya/"><![CDATA[<p>Bir drone’u havada tutmak, dört motoru çalıştırıp şans dilemekten çok daha fazlasıdır. Uçuş kontrolcüsü; sensörleri okuyan, aracın mevcut durumunu tahmin eden ve motorlara saniyede yüzlerce kez düzeltme komutu gönderen gerçek zamanlı bir bilgisayardır. Manuel dengeden GPS destekli otonom rotaya kadar bütün uçuş yetenekleri, iç içe çalışan kontrol döngülerine dayanır.</p>

<p>``</p>

<h2 id="önce-drone-neyi-kontrol-eder">Önce drone neyi kontrol eder?</h2>

<p>Bir quadcopter’ın hareketi dört temel eksen üzerinden açıklanır:</p>

<table>
  <thead>
    <tr>
      <th>Eksen</th>
      <th>Anlamı</th>
      <th>Motorların tepkisi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Roll</td>
      <td>Sağa veya sola yatış</td>
      <td>Bir taraftaki itki artırılır</td>
    </tr>
    <tr>
      <td>Pitch</td>
      <td>Öne veya arkaya yatış</td>
      <td>Ön-arka motor dengesi değiştirilir</td>
    </tr>
    <tr>
      <td>Yaw</td>
      <td>Kendi ekseninde dönüş</td>
      <td>Zıt yönde dönen motorlar ayarlanır</td>
    </tr>
    <tr>
      <td>Throttle</td>
      <td>Yükselme ve alçalma</td>
      <td>Tüm motorların itkisi değiştirilir</td>
    </tr>
  </tbody>
</table>

<p>Kontrolcü, jiroskoptan açısal hızı, ivmeölçerden doğrusal ivmeyi, barometreden yüksekliği ve GPS’ten konumu alır. Ancak hiçbir sensör kusursuz değildir. Jiroskop zamanla sürüklenirken ivmeölçer titreşimlerden etkilenir. Bu nedenle tamamlayıcı filtre veya Kalman filtresi gibi <strong>sensör füzyonu</strong> yöntemleri kullanılır.</p>

<p>Basit bir açı tahmini şöyle düşünülebilir:</p>

\[aci = α(aci + jiroskop \cdot Δt) + (1-α)ivmeolcerAcisi\]

<p>Burada $α$, hızlı fakat sürüklenen jiroskop ile yavaş fakat referans sağlayan ivmeölçer arasındaki güven dengesidir.</p>

<h2 id="pid-dengeyi-sağlayan-üçlü">PID: Dengeyi sağlayan üçlü</h2>

<p>PID kontrolcü, hedef değer ile ölçülen değer arasındaki $e(t)$ hatasını motor komutuna dönüştürür:</p>

\[u(t)=K_p e(t)+K_i\int e(t)dt+K_d\frac{de(t)}{dt}\]

<table>
  <thead>
    <tr>
      <th>Bileşen</th>
      <th>Görevi</th>
      <th>Fazla olduğunda</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>P</td>
      <td>Mevcut hataya tepki verir</td>
      <td>Drone salınım yapar</td>
    </tr>
    <tr>
      <td>I</td>
      <td>Birikmiş kalıcı hatayı giderir</td>
      <td>Yavaş dalgalanma oluşur</td>
    </tr>
    <tr>
      <td>D</td>
      <td>Hatanın değişimini frenler</td>
      <td>Gürültü ve motor ısınması artar</td>
    </tr>
  </tbody>
</table>

<p>Örneğin roll hedefi $0°$, ölçülen açı $8°$ ise PID, drone’u ters yönde yatıracak motor düzeltmesini üretir. Gerçek sistemlerde genellikle iç içe döngüler bulunur: dış döngü açı hedefini açısal hız hedefine, iç döngü ise açısal hız hatasını motor komutuna çevirir. İç döngü daha hızlı çalışır; çünkü önce gövde dengede kalmalıdır.</p>

<p>Aşağıdaki sade Python örneği tek eksenli PID hesabını gösterir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">PID</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">kp</span><span class="p">,</span> <span class="n">ki</span><span class="p">,</span> <span class="n">kd</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">kp</span><span class="p">,</span> <span class="n">self</span><span class="p">.</span><span class="n">ki</span><span class="p">,</span> <span class="n">self</span><span class="p">.</span><span class="n">kd</span> <span class="o">=</span> <span class="n">kp</span><span class="p">,</span> <span class="n">ki</span><span class="p">,</span> <span class="n">kd</span>
        <span class="n">self</span><span class="p">.</span><span class="n">integral</span> <span class="o">=</span> <span class="mf">0.0</span>
        <span class="n">self</span><span class="p">.</span><span class="n">previous_error</span> <span class="o">=</span> <span class="mf">0.0</span>

    <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">measured</span><span class="p">,</span> <span class="n">dt</span><span class="p">):</span>
        <span class="n">error</span> <span class="o">=</span> <span class="n">target</span> <span class="o">-</span> <span class="n">measured</span>
        <span class="n">self</span><span class="p">.</span><span class="n">integral</span> <span class="o">+=</span> <span class="n">error</span> <span class="o">*</span> <span class="n">dt</span>
        <span class="n">derivative</span> <span class="o">=</span> <span class="p">(</span><span class="n">error</span> <span class="o">-</span> <span class="n">self</span><span class="p">.</span><span class="n">previous_error</span><span class="p">)</span> <span class="o">/</span> <span class="n">dt</span>
        <span class="n">self</span><span class="p">.</span><span class="n">previous_error</span> <span class="o">=</span> <span class="n">error</span>

        <span class="nf">return </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">kp</span> <span class="o">*</span> <span class="n">error</span>
                <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">ki</span> <span class="o">*</span> <span class="n">self</span><span class="p">.</span><span class="n">integral</span>
                <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">kd</span> <span class="o">*</span> <span class="n">derivative</span><span class="p">)</span>
</code></pre></div></div>

<p>Dönen değer doğrudan tek motora verilmez. Bir <strong>mixer</strong>, roll, pitch, yaw ve throttle çıktılarını drone geometrisine göre dört motora dağıtır. Komutlar ayrıca güvenli motor aralığında sınırlandırılır; integral teriminin kontrolden çıkmaması için anti-windup uygulanır.</p>

<h2 id="denge-kontrolünden-otonom-rotaya">Denge kontrolünden otonom rotaya</h2>

<p>Otonom uçuş, PID’yi ortadan kaldırmaz; onun üzerine yeni katmanlar ekler. Rota planlayıcı waypoint’leri belirler, konum kontrolcüsü istenen hız ve yatışı hesaplar, tutum kontrolcüsü de bu hedefleri motorlara uygular.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Görev planı → Konum hedefi → Hız hedefi
           → Açı hedefi → Açısal hız → Motorlar
</code></pre></div></div>

<p>Drone hedef noktanın kuzeyinde kaldıysa konum döngüsü güneye doğru hız ister. Hız döngüsü bunu uygun pitch ve roll açılarına çevirir. En içteki PID döngüleri ise bu açıları fiziksel olarak gerçekleştirir. Engel algılama eklendiğinde kamera, lidar veya ultrasonik sensörlerden gelen veriler rota planlayıcıya aktarılır.</p>

<p>A* algoritması harita üzerinde düşük maliyetli bir yol bulabilirken RRT, karmaşık ve sürekli uzaylarda hızlı aday rotalar üretir. Fakat planlanan rota uçulabilir olmalıdır; keskin dönüşler, maksimum eğim, batarya ve rüzgâr hesaba katılmalıdır.</p>

<p>Sonuç olarak otonom drone, tek bir akıllı algoritmadan değil, farklı hızlarda çalışan güvenilir katmanlardan oluşur. PID refleksleri, sensör füzyonu denge hissini, rota planlama ise yön duygusunu sağlar. Gökyüzündeki zarif hareketin arkasında sürekli hata hesaplayan oldukça çalışkan bir matematik ekibi vardır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="drone" /><category term="pid" /><category term="otonom uçuş" /><category term="uçuş kontrolü" /><category term="sensör füzyonu" /><category term="robotik" /><summary type="html"><![CDATA[Bir drone’u havada tutmak, dört motoru çalıştırıp şans dilemekten çok daha fazlasıdır. Uçuş kontrolcüsü; sensörleri okuyan, aracın mevcut durumunu tahmin eden ve motorlara saniyede yüzlerce kez düzeltme komutu gönderen gerçek zamanlı bir bilgisayardır. Manuel dengeden GPS destekli otonom rotaya kadar bütün uçuş yetenekleri, iç içe çalışan kontrol döngülerine dayanır.]]></summary></entry><entry><title type="html">Encoder ve Step Motorlarla Hassas Hareket Kontrolü</title><link href="https://program.sonsuz.us/posts/encoder-ve-step-motorlarla-hassas-hareket-kontrolu/" rel="alternate" type="text/html" title="Encoder ve Step Motorlarla Hassas Hareket Kontrolü" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/encoder-ve-step-motorlarla-hassas-hareket-kontrolu</id><content type="html" xml:base="https://program.sonsuz.us/posts/encoder-ve-step-motorlarla-hassas-hareket-kontrolu/"><![CDATA[<p>Step motorlar komutları adım adım uygulayan disiplinli çalışanlara benzer; encoderlar ise işin gerçekten yapılıp yapılmadığını denetleyen dikkatli yöneticilerdir. Bu ikili doğru bir kontrol algoritmasıyla birleştirildiğinde CNC tezgâhlarından robot kollarına kadar pek çok sistemde hassas, tekrarlanabilir ve güvenilir hareket elde edilir. Gelin açık çevrim rahatlığından kapalı çevrim hassasiyetine uzanan bu mekanik yolculuğa çıkalım.</p>

<p>``</p>

<h2 id="step-motorun-hareket-mantığı">Step motorun hareket mantığı</h2>

<p>Step motor, elektrik darbelerini belirli açısal hareketlere dönüştürür. Örneğin tur başına 200 adımı bulunan bir motorun doğal adım açısı:</p>

\[A = 360 / 200 = 1.8^\circ\]

<p>Sürücü 16 mikro adım modunda çalıştırılırsa teorik çözünürlük tur başına $200 \times 16 = 3200$ mikro adıma yükselir. Hedef açı için gönderilmesi gereken darbe sayısı şöyle hesaplanır:</p>

\[N = (H / 360) \times S \times M\]

<p>Burada $H$ hedef açıyı, $S$ motorun tam adım sayısını, $M$ ise mikro adım katsayısını ifade eder. Ancak mikro adım kullanmak her zaman aynı oranda gerçek mekanik doğruluk sağlamaz. Motor torku, yük, boşluk ve sürtünme sonucu etkiler.</p>

<h2 id="encoder-neden-gereklidir">Encoder neden gereklidir?</h2>

<p>Step motor sürücüsü darbe gönderildiğinde motorun hareket ettiğini varsayar. Yük fazla gelirse motor adım kaçırabilir ve kontrol sistemi bundan haberdar olmayabilir. Encoder ise motor milinin gerçek konumunu ölçerek varsayımı ölçülebilir bilgiye dönüştürür.</p>

<p>Artımlı quadrature encoderlarda A ve B adlı iki kanal arasında faz farkı bulunur. Bu sayede hem hareket miktarı hem de yön belirlenebilir. Encoder tur başına $P$ darbe üretiyor ve dört kenar sayımı kullanılıyorsa açısal konum yaklaşık olarak:</p>

\[Q = C \times 360 / (4P)\]

<p>formülüyle bulunur. Burada $C$, sayılan encoder kenarıdır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Açık çevrim step motor</th>
      <th>Encoder geri beslemeli sistem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Konum bilgisi</td>
      <td>Tahmin edilir</td>
      <td>Ölçülür</td>
    </tr>
    <tr>
      <td>Adım kaçırma</td>
      <td>Fark edilmez</td>
      <td>Algılanabilir</td>
    </tr>
    <tr>
      <td>Yazılım karmaşıklığı</td>
      <td>Düşük</td>
      <td>Orta veya yüksek</td>
    </tr>
    <tr>
      <td>Yük değişimine dayanım</td>
      <td>Sınırlı</td>
      <td>Daha güçlü</td>
    </tr>
    <tr>
      <td>Kalibrasyon ihtiyacı</td>
      <td>Az</td>
      <td>Daha fazla</td>
    </tr>
  </tbody>
</table>

<h2 id="kapalı-çevrim-kontrol">Kapalı çevrim kontrol</h2>

<p>Kontrol sisteminde hedef konum ile encoderın ölçtüğü konum karşılaştırılır:</p>

\[e(t) = hedef(t) - ölçüm(t)\]

<p>Ortaya çıkan hata pozitifse motor ileri, negatifse geri hareket ettirilir. Basit uygulamalarda hata büyüklüğüne göre step frekansı ayarlanabilir. Daha akıcı sistemlerde PID kontrolü kullanılır:</p>

\[u(t) = K_p e(t) + K_i \int e(t)dt + K_d de(t)/dt\]

<p>Oransal terim mevcut hataya tepki verir, integral terimi kalıcı hatayı azaltır, türev terimi ise ani değişimleri frenler. Yanlış ayarlanmış PID, hassasiyet yerine masada dans eden bir motor üretebilir; bu nedenle düşük kazançlarla başlamak güvenlidir.</p>

<h2 id="arduino-ile-temel-uygulama">Arduino ile temel uygulama</h2>

<p>Aşağıdaki örnek encoder sayımını izler ve hedefe göre motor yönünü belirler. Kesme kullanılması, hızlı encoder darbelerinin kaçırılma riskini azaltır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="kt">int</span> <span class="n">stepPin</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">dirPin</span> <span class="o">=</span> <span class="mi">6</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">encA</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">encB</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>

<span class="k">volatile</span> <span class="kt">long</span> <span class="n">encoderCount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">targetCount</span> <span class="o">=</span> <span class="mi">4000</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">readEncoder</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">digitalRead</span><span class="p">(</span><span class="n">encA</span><span class="p">)</span> <span class="o">==</span> <span class="n">digitalRead</span><span class="p">(</span><span class="n">encB</span><span class="p">))</span>
    <span class="n">encoderCount</span><span class="o">++</span><span class="p">;</span>
  <span class="k">else</span>
    <span class="n">encoderCount</span><span class="o">--</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">makeStep</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">stepPin</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
  <span class="n">delayMicroseconds</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">stepPin</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
  <span class="n">delayMicroseconds</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">pinMode</span><span class="p">(</span><span class="n">stepPin</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
  <span class="n">pinMode</span><span class="p">(</span><span class="n">dirPin</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
  <span class="n">pinMode</span><span class="p">(</span><span class="n">encA</span><span class="p">,</span> <span class="n">INPUT_PULLUP</span><span class="p">);</span>
  <span class="n">pinMode</span><span class="p">(</span><span class="n">encB</span><span class="p">,</span> <span class="n">INPUT_PULLUP</span><span class="p">);</span>
  <span class="n">attachInterrupt</span><span class="p">(</span><span class="n">digitalPinToInterrupt</span><span class="p">(</span><span class="n">encA</span><span class="p">),</span> <span class="n">readEncoder</span><span class="p">,</span> <span class="n">CHANGE</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kt">long</span> <span class="n">error</span> <span class="o">=</span> <span class="n">targetCount</span> <span class="o">-</span> <span class="n">encoderCount</span><span class="p">;</span>

  <span class="k">if</span> <span class="p">(</span><span class="n">abs</span><span class="p">(</span><span class="n">error</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">dirPin</span><span class="p">,</span> <span class="n">error</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="n">HIGH</span> <span class="o">:</span> <span class="n">LOW</span><span class="p">);</span>
    <span class="n">makeStep</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>İki sayımlık tolerans bölgesi motorun hedef çevresinde sürekli ileri geri titreşmesini önler. Gerçek projede hızlanma ve yavaşlama rampaları eklenmeli; aksi hâlde motor yüksek frekansta aniden başlatıldığında adım kaçırabilir.</p>

<h2 id="mekanik-ayrıntıları-unutmayın">Mekanik ayrıntıları unutmayın</h2>

<p>Yazılım kusursuz olsa bile kaplin boşluğu, kayış esnemesi ve rulman toleransı sonucu bozabilir. Encoder motor milindeyse motor hareketini ölçer, fakat yük tarafındaki boşluğu göremeyebilir. Çok yüksek doğruluk gereken makinelerde encoderın doğrudan hareketli eksene yerleştirilmesi daha doğrudur.</p>

<p>Sonuç olarak step motor komutu, encoder gerçeği, kontrol algoritması ise ikisi arasındaki uzlaşmayı temsil eder. Sağlam mekanik, doğru elektrik bağlantıları ve dikkatli ayarlanmış kontrol parametreleri birleştiğinde mikrometre seviyesine yaklaşan hareketler ulaşılabilir bir mühendislik hedefi hâline gelir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="encoder" /><category term="step-motor" /><category term="pid" /><category term="arduino" /><category term="hareket-kontrolü" /><category term="otomasyon" /><summary type="html"><![CDATA[Step motorlar komutları adım adım uygulayan disiplinli çalışanlara benzer; encoderlar ise işin gerçekten yapılıp yapılmadığını denetleyen dikkatli yöneticilerdir. Bu ikili doğru bir kontrol algoritmasıyla birleştirildiğinde CNC tezgâhlarından robot kollarına kadar pek çok sistemde hassas, tekrarlanabilir ve güvenilir hareket elde edilir. Gelin açık çevrim rahatlığından kapalı çevrim hassasiyetine uzanan bu mekanik yolculuğa çıkalım.]]></summary></entry><entry><title type="html">Kalman Filtresiyle Sensör Füzyonu: Gürültüden Güvenilir Konuma</title><link href="https://program.sonsuz.us/posts/kalman-filtresiyle-sensor-fuzyonu-gurultuden-guvenilir-konuma/" rel="alternate" type="text/html" title="Kalman Filtresiyle Sensör Füzyonu: Gürültüden Güvenilir Konuma" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kalman-filtresiyle-sensor-fuzyonu-gurultuden-guvenilir-konuma</id><content type="html" xml:base="https://program.sonsuz.us/posts/kalman-filtresiyle-sensor-fuzyonu-gurultuden-guvenilir-konuma/"><![CDATA[<p>Bir robotun GPS verisi bir sağa bir sola sıçrarken ivmeölçeri en küçük titreşimi bile hareket sanabilir. Peki telefonlar, dronlar ve otonom araçlar bu karmaşadan nasıl düzgün bir konum çıkarır? Cevap çoğu zaman Kalman filtresidir: Ölçümlere körü körüne inanmak yerine model ile sensörler arasında matematiksel bir güven pazarlığı yapan akıllı bir tahmin mekanizması.</p>

<p>``</p>

<h2 id="temel-fikir-tahmin-et-ölç-düzelt">Temel fikir: Tahmin et, ölç, düzelt</h2>

<p>Kalman filtresi, sistemin durumunu doğrudan bilmediğimizi kabul eder. Bunun yerine konum ve hız gibi değişkenleri bir <strong>durum vektöründe</strong> toplar. Tek boyutlu hareket için şöyle bir vektör kullanabiliriz:</p>

\[x_k = [p_k, v_k]^T\]

<p>Burada $p_k$ konumu, $v_k$ hızı, $k$ ise zaman adımını gösterir. Sabit hızlı hareket varsayımında yeni durumun modeli şöyledir:</p>

\[x_k = F x_{k-1} + w_k\]

<p>$F$ durum geçiş matrisi, $w_k$ ise modelin açıklayamadığı süreç gürültüsüdür. Zaman aralığı $dt$ olduğunda geçiş matrisi $F = [[1, dt], [0, 1]]$ biçimindedir. Yani yeni konum, eski konuma hız çarpı zaman eklenerek bulunur.</p>

<p>Sensör ölçümü ise şu modelle ifade edilir:</p>

\[z_k = H x_k + v_k\]

<p>Buradaki $H$, durumun hangi bölümünün ölçüldüğünü; $v_k$ ise sensör gürültüsünü temsil eder. Örneğin GPS yalnızca konum veriyorsa $H = [1, 0]$ olur.</p>

<h2 id="sensörler-neden-birleştirilir">Sensörler neden birleştirilir?</h2>

<p>Her sensörün farklı bir süper gücü ve zayıflığı vardır:</p>

<table>
  <thead>
    <tr>
      <th>Sensör</th>
      <th>Güçlü yanı</th>
      <th>Zayıf yanı</th>
      <th>Füzyondaki rolü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GPS</td>
      <td>Uzun vadede mutlak konum verir</td>
      <td>Gürültülü ve yavaştır</td>
      <td>Biriken hatayı düzeltir</td>
    </tr>
    <tr>
      <td>İvmeölçer</td>
      <td>Hızlı tepki verir</td>
      <td>Sapma zamanla büyür</td>
      <td>Kısa süreli hareketi izler</td>
    </tr>
    <tr>
      <td>Jiroskop</td>
      <td>Dönüşleri hassas ölçer</td>
      <td>Drift üretir</td>
      <td>Yönelim değişimini yakalar</td>
    </tr>
    <tr>
      <td>Enkoder</td>
      <td>Tekerlek hareketini ölçer</td>
      <td>Kaymada yanılır</td>
      <td>Yerel hareket tahmini sağlar</td>
    </tr>
  </tbody>
</table>

<p>Kalman filtresi hızlı sensörlerle sık tahmin yapıp GPS gibi mutlak ölçümler geldiğinde sonucu düzeltir. Böylece GPS’in sıçramaları yumuşatılırken yalnızca IMU kullanmanın oluşturacağı sürüklenme de sınırlandırılır.</p>

<h2 id="belirsizlik-işin-merkezinde">Belirsizlik işin merkezinde</h2>

<p>Filtre yalnızca konumu değil, tahminine ne kadar güvendiğini de taşır. Bu güven, $P$ hata kovaryans matrisiyle temsil edilir. Süreç gürültüsü kovaryansı $Q$, hareket modelinin; ölçüm gürültüsü kovaryansı $R$ ise sensörün belirsizliğini anlatır.</p>

<p>Tahmin aşaması:</p>

\[x_k^- = F x_{k-1}\]

\[P_k^- = F P_{k-1} F^T + Q\]

<p>Düzeltme aşamasında önce Kalman kazancı hesaplanır:</p>

\[K_k = P_k^- H^T (H P_k^- H^T + R)^{-1}\]

<p>$R$ büyükse filtre sensöre daha az, modele daha çok güvenir. $P$ büyüdüğünde ise yeni ölçüm daha etkili olur. Ardından ölçüm ile tahmin arasındaki fark kullanılır:</p>

\[x_k = x_k^- + K_k(z_k - Hx_k^-)\]

<h2 id="python-ile-basit-konum-filtresi">Python ile basit konum filtresi</h2>

<p>Aşağıdaki sınıf, sabit hızlı tek boyutlu hareketi izler ve gürültülü konum ölçümlerini süzer:</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="k">class</span> <span class="nc">PositionKalman</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">dt</span><span class="p">,</span> <span class="n">process_noise</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span> <span class="n">measurement_noise</span><span class="o">=</span><span class="mf">4.0</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([[</span><span class="mf">0.0</span><span class="p">],</span> <span class="p">[</span><span class="mf">0.0</span><span class="p">]])</span>  <span class="c1"># konum, hız
</span>        <span class="n">self</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">array</span><span class="p">([[</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">dt</span><span class="p">],</span> <span class="p">[</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">]])</span>
        <span class="n">self</span><span class="p">.</span><span class="n">H</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([[</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">]])</span>
        <span class="n">self</span><span class="p">.</span><span class="n">P</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">eye</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="mf">10.0</span>
        <span class="n">self</span><span class="p">.</span><span class="n">Q</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">eye</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="n">process_noise</span>
        <span class="n">self</span><span class="p">.</span><span class="n">R</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([[</span><span class="n">measurement_noise</span><span class="p">]])</span>
        <span class="n">self</span><span class="p">.</span><span class="n">I</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">eye</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">predict</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">F</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">x</span>
        <span class="n">self</span><span class="p">.</span><span class="n">P</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">F</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">P</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">F</span><span class="p">.</span><span class="n">T</span> <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">Q</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>

    <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">measured_position</span><span class="p">):</span>
        <span class="n">z</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([[</span><span class="n">measured_position</span><span class="p">]])</span>
        <span class="n">innovation</span> <span class="o">=</span> <span class="n">z</span> <span class="o">-</span> <span class="n">self</span><span class="p">.</span><span class="n">H</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">x</span>
        <span class="n">innovation_cov</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">H</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">P</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">H</span><span class="p">.</span><span class="n">T</span> <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">R</span>
        <span class="n">K</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">P</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">H</span><span class="p">.</span><span class="n">T</span> <span class="o">@</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">inv</span><span class="p">(</span><span class="n">innovation_cov</span><span class="p">)</span>

        <span class="n">self</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">K</span> <span class="o">@</span> <span class="n">innovation</span>
        <span class="n">self</span><span class="p">.</span><span class="n">P</span> <span class="o">=</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">I</span> <span class="o">-</span> <span class="n">K</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">H</span><span class="p">)</span> <span class="o">@</span> <span class="n">self</span><span class="p">.</span><span class="n">P</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">predict()</code> hareket modeline göre ara konumu üretir. <code class="language-plaintext highlighter-rouge">update()</code> ise GPS benzeri bir ölçüm geldiğinde yenilik değerini hesaplayıp tahmini düzeltir. Gerçek uygulamalarda $Q$ ve $R$ değerleri sensör kayıtları incelenerek ayarlanmalıdır; yanlış ayar, filtrenin ya aşırı titrek ya da tembel olmasına neden olur.</p>

<p>Kalman filtresi sihirli bir gürültü silgisi değildir. Doğru hareket modeli, gerçekçi belirsizlikler ve sensörlerin zaman eşlemesi şarttır. Ancak bu parçalar yerli yerine oturduğunda, birbirinden şüpheli sensörler birlikte oldukça güvenilir bir konum anlatmaya başlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="kalman filtresi" /><category term="sensör füzyonu" /><category term="konum kestirimi" /><category term="python" /><category term="imu" /><category term="gps" /><summary type="html"><![CDATA[Bir robotun GPS verisi bir sağa bir sola sıçrarken ivmeölçeri en küçük titreşimi bile hareket sanabilir. Peki telefonlar, dronlar ve otonom araçlar bu karmaşadan nasıl düzgün bir konum çıkarır? Cevap çoğu zaman Kalman filtresidir: Ölçümlere körü körüne inanmak yerine model ile sensörler arasında matematiksel bir güven pazarlığı yapan akıllı bir tahmin mekanizması.]]></summary></entry><entry><title type="html">Kamera Robotun Gözü Olduğunda: Bilgisayarlı Görüyle Nesne Takibi</title><link href="https://program.sonsuz.us/posts/kamera-robotun-gozu-oldugunda-bilgisayarli-goruyle-nesne-takibi/" rel="alternate" type="text/html" title="Kamera Robotun Gözü Olduğunda: Bilgisayarlı Görüyle Nesne Takibi" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kamera-robotun-gozu-oldugunda-bilgisayarli-goruyle-nesne-takibi</id><content type="html" xml:base="https://program.sonsuz.us/posts/kamera-robotun-gozu-oldugunda-bilgisayarli-goruyle-nesne-takibi/"><![CDATA[<p>Bir robotun hareket eden topu izlemesi, raftaki kutuya yönelmesi veya sahibini takip etmesi dışarıdan sihirli görünebilir. Oysa perde arkasında kamera görüntülerini sayılara dönüştüren bilgisayarlı görü, hedefin konumunu tahmin eden algoritmalar ve motorlara komut veren kontrol mekanizmaları birlikte çalışır. Kamera robotun gözü ise nesne takip sistemi de dikkatini nereye yönelteceğine karar veren beynidir.</p>

<p>``</p>

<h2 id="görüntüden-harekete-uzanan-zincir">Görüntüden harekete uzanan zincir</h2>

<p>Kamera gerçekte nesneleri değil, piksellerden oluşan kareleri görür. Her karede hedef nesne bulunur, önceki karedeki konumuyla ilişkilendirilir ve robotun nasıl hareket edeceği hesaplanır. Temel işlem hattı şöyledir:</p>

<ol>
  <li>Kameradan yeni bir görüntü karesi alınır.</li>
  <li>Hedef nesne algılanır veya takip edilir.</li>
  <li>Nesnenin merkez koordinatı hesaplanır.</li>
  <li>Görüntü merkeziyle hedef merkezi arasındaki hata bulunur.</li>
  <li>Hata, motor hızına ya da direksiyon açısına dönüştürülür.</li>
</ol>

<p>Görüntünün genişliği $W$, hedef merkezinin yatay koordinatı $x_t$ olsun. Robotun yönelme hatası:</p>

\[e_x = x_t - \frac{W}{2}\]

<p>şeklinde hesaplanabilir. $e_x &lt; 0$ ise hedef solda, $e_x &gt; 0$ ise sağdadır. Hata sıfıra yaklaştıkça robot hedefe bakıyor demektir. Perspektif kamera modelinde bir noktanın görüntü koordinatı yaklaşık olarak</p>

\[x = f\frac{X}{Z}, \qquad y = f\frac{Y}{Z}\]

<p>ile ifade edilir. Burada $f$ odak uzaklığı, $Z$ ise nesnenin kameraya olan derinliğidir. Bu nedenle nesne yaklaştıkça görüntüde büyür; yalnızca kutu boyutuna bakarak yaklaşık mesafe tahmini yapılabilir.</p>

<h2 id="algılama-mı-takip-mi">Algılama mı, takip mi?</h2>

<p>Bu iki kavram sıkça aynı sanılır, ancak görevleri farklıdır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Ne yapar?</th>
      <th>Avantajı</th>
      <th>Dezavantajı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Nesne algılama</td>
      <td>Her karede hedefi yeniden bulur</td>
      <td>Kaybolan hedefi tekrar yakalayabilir</td>
      <td>Daha fazla işlem gücü ister</td>
    </tr>
    <tr>
      <td>Nesne takibi</td>
      <td>Önceden seçilen hedefin hareketini izler</td>
      <td>Hızlıdır</td>
      <td>Örtülme durumunda hedefi kaybedebilir</td>
    </tr>
    <tr>
      <td>Hibrit sistem</td>
      <td>Algılama ve takibi birlikte kullanır</td>
      <td>Daha dayanıklıdır</td>
      <td>Tasarımı daha karmaşıktır</td>
    </tr>
  </tbody>
</table>

<p>YOLO gibi sinir ağı tabanlı algılayıcılar hedefi sınıfıyla birlikte bulabilir. KCF, CSRT ve optik akış gibi takip yöntemleri ise ardışık karelerdeki değişimden yararlanır. Pratik bir robot, hedefi belirli aralıklarla algılayıp aradaki karelerde daha hızlı bir takipçi kullanabilir.</p>

<h2 id="opencv-ile-basit-renk-takibi">OpenCV ile basit renk takibi</h2>

<p>Aşağıdaki örnek, turuncu bir nesneyi HSV renk uzayında ayırır ve yatay hataya göre robotun yönünü belirler:</p>

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

<span class="n">camera</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nc">VideoCapture</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="n">ok</span><span class="p">,</span> <span class="n">frame</span> <span class="o">=</span> <span class="n">camera</span><span class="p">.</span><span class="nf">read</span><span class="p">()</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">ok</span><span class="p">:</span>
        <span class="k">break</span>

    <span class="n">hsv</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">cvtColor</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">cv2</span><span class="p">.</span><span class="n">COLOR_BGR2HSV</span><span class="p">)</span>
    <span class="n">lower</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="mi">5</span><span class="p">,</span> <span class="mi">120</span><span class="p">,</span> <span class="mi">120</span><span class="p">])</span>
    <span class="n">upper</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="mi">20</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">])</span>
    <span class="n">mask</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">inRange</span><span class="p">(</span><span class="n">hsv</span><span class="p">,</span> <span class="n">lower</span><span class="p">,</span> <span class="n">upper</span><span class="p">)</span>

    <span class="n">contours</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">findContours</span><span class="p">(</span>
        <span class="n">mask</span><span class="p">,</span> <span class="n">cv2</span><span class="p">.</span><span class="n">RETR_EXTERNAL</span><span class="p">,</span> <span class="n">cv2</span><span class="p">.</span><span class="n">CHAIN_APPROX_SIMPLE</span>
    <span class="p">)</span>

    <span class="k">if</span> <span class="n">contours</span><span class="p">:</span>
        <span class="n">target</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="n">contours</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">cv2</span><span class="p">.</span><span class="n">contourArea</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">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">boundingRect</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">center_x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">w</span> <span class="o">//</span> <span class="mi">2</span>
        <span class="n">error</span> <span class="o">=</span> <span class="n">center_x</span> <span class="o">-</span> <span class="n">frame</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">//</span> <span class="mi">2</span>

        <span class="n">command</span> <span class="o">=</span> <span class="sh">'</span><span class="s">sola dön</span><span class="sh">'</span> <span class="k">if</span> <span class="n">error</span> <span class="o">&lt;</span> <span class="o">-</span><span class="mi">30</span> <span class="k">else</span> <span class="sh">'</span><span class="s">sağa dön</span><span class="sh">'</span> <span class="k">if</span> <span class="n">error</span> <span class="o">&gt;</span> <span class="mi">30</span> <span class="k">else</span> <span class="sh">'</span><span class="s">ileri</span><span class="sh">'</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="sh">'</span><span class="s">hata:</span><span class="sh">'</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span>
        <span class="n">cv2</span><span class="p">.</span><span class="nf">rectangle</span><span class="p">(</span><span class="n">frame</span><span class="p">,</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="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">w</span><span class="p">,</span> <span class="n">y</span> <span class="o">+</span> <span class="n">h</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span>

    <span class="n">cv2</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="sh">'</span><span class="s">Robot Gözü</span><span class="sh">'</span><span class="p">,</span> <span class="n">frame</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">waitKey</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="mi">27</span><span class="p">:</span>
        <span class="k">break</span>

<span class="n">camera</span><span class="p">.</span><span class="nf">release</span><span class="p">()</span>
<span class="n">cv2</span><span class="p">.</span><span class="nf">destroyAllWindows</span><span class="p">()</span>
</code></pre></div></div>

<p>Kod, en büyük renk bölgesini hedef kabul eder. Gerçek robotta <code class="language-plaintext highlighter-rouge">command</code> değişkeni seri port, ROS mesajı veya motor sürücü kartı üzerinden fiziksel harekete çevrilir.</p>

<h2 id="robot-neden-titrer">Robot neden titrer?</h2>

<p>Ham hata doğrudan motorlara gönderilirse robot sürekli sağa sola oynayabilir. Bunun çözümü PID kontrolüdür:</p>

\[u(t)=K_p e(t)+K_i\int e(t)dt+K_d\frac{de(t)}{dt}\]

<p>$K_p$ anlık hataya tepki verir, $K_i$ kalıcı sapmayı azaltır, $K_d$ ise ani değişimleri yumuşatır. Ayrıca küçük hataların yok sayıldığı bir ölü bölge, görüntü filtreleme ve maksimum hız sınırı sistemi sakinleştirir.</p>

<p>Işık değişimi, hareket bulanıklığı ve nesnenin başka bir cismin arkasına geçmesi gerçek dünyanın sürprizleridir. Kalman filtresiyle konum tahmini, iyi kamera kalibrasyonu ve algılama-takip hibriti kullanıldığında robot yalnızca bakmaz; gördüğünü anlamlandırıp güvenli biçimde peşinden gider.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="bilgisayarlı görü" /><category term="robotik" /><category term="nesne takibi" /><category term="opencv" /><category term="python" /><category term="pid kontrol" /><summary type="html"><![CDATA[Bir robotun hareket eden topu izlemesi, raftaki kutuya yönelmesi veya sahibini takip etmesi dışarıdan sihirli görünebilir. Oysa perde arkasında kamera görüntülerini sayılara dönüştüren bilgisayarlı görü, hedefin konumunu tahmin eden algoritmalar ve motorlara komut veren kontrol mekanizmaları birlikte çalışır. Kamera robotun gözü ise nesne takip sistemi de dikkatini nereye yönelteceğine karar veren beynidir.]]></summary></entry><entry><title type="html">Kendi Kendine Dengelenen Robot: Ters Sarkacı İki Teker Üzerinde Ehlileştirmek</title><link href="https://program.sonsuz.us/posts/kendi-kendine-dengelenen-robot-ters-sarkaci-iki-teker-uzerinde-ehlilestirmek/" rel="alternate" type="text/html" title="Kendi Kendine Dengelenen Robot: Ters Sarkacı İki Teker Üzerinde Ehlileştirmek" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-kendine-dengelenen-robot-ters-sarkaci-iki-teker-uzerinde-ehlilestirmek</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-kendine-dengelenen-robot-ters-sarkaci-iki-teker-uzerinde-ehlilestirmek/"><![CDATA[<p>İki tekerlek üzerinde duran bir robot, fizik kurallarına meydan okuyor gibi görünür. Oysa yaptığı şey düşmeyi engellemek değil, düşüşünü sürekli ölçüp tekerleklerini doğru yöne sürerek gövdesini yeniden dengelemektir. Bu proje; mekanik, elektronik, sensör füzyonu ve kontrol teorisini eğlenceli biçimde bir araya getirir.</p>

<p>``</p>

<h2 id="ters-sarkaç-neden-kararsızdır">Ters sarkaç neden kararsızdır?</h2>

<p>Normal bir sarkaç aşağı doğru durduğunda kararlıdır; küçük bir itmeden sonra tekrar denge noktasına döner. Ters sarkaçta ise ağırlık merkezi dönme ekseninin üzerindedir. Çok küçük bir açı hatası bile yerçekimi torku oluşturarak sapmayı büyütür.</p>

<p>Basitleştirilmiş yerçekimi torku şöyle yazılabilir:</p>

\[\tau_g = m g l \sin(\theta)\]

<p>Burada $m$ gövde kütlesi, $g$ yerçekimi ivmesi, $l$ ağırlık merkezinin tekerlek eksenine uzaklığı ve $\theta$ eğim açısıdır. Küçük açılarda $\sin(\theta) \approx \theta$ kabul edilir. Böylece sistem yaklaşık doğrusal modellenebilir; fakat kendi hâline bırakıldığında hâlâ kararsızdır.</p>

<p>Robotun görevi, motorların ürettiği karşı torkla bu sapmayı bastırmaktır. Başka bir ifadeyle robot öne düşüyorsa tekerlekler öne kaçmalı, arkaya düşüyorsa arkaya gitmelidir.</p>

<h2 id="gerekli-bileşenler">Gerekli bileşenler</h2>

<table>
  <thead>
    <tr>
      <th>Bileşen</th>
      <th>Görevi</th>
      <th>Seçim notu</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Mikrodenetleyici</td>
      <td>Kontrol döngüsünü çalıştırır</td>
      <td>Arduino Nano, ESP32 veya STM32 kullanılabilir</td>
    </tr>
    <tr>
      <td>IMU</td>
      <td>Açısal hız ve ivme ölçer</td>
      <td>MPU6050 ekonomik bir başlangıçtır</td>
    </tr>
    <tr>
      <td>DC motor ve enkoder</td>
      <td>Hareket ve konum geri bildirimi sağlar</td>
      <td>Boşluksuz redüktör tercih edilmelidir</td>
    </tr>
    <tr>
      <td>Motor sürücü</td>
      <td>Motor akımını kontrol eder</td>
      <td>TB6612FNG, L298N’den daha verimlidir</td>
    </tr>
    <tr>
      <td>Batarya</td>
      <td>Sistemi besler</td>
      <td>Ani motor akımını karşılayabilmelidir</td>
    </tr>
    <tr>
      <td>Şasi ve tekerlekler</td>
      <td>Mekanik yapıyı oluşturur</td>
      <td>Ağırlık merkezi eksenin üzerinde olmalıdır</td>
    </tr>
  </tbody>
</table>

<h2 id="açıyı-doğru-ölçmek">Açıyı doğru ölçmek</h2>

<p>İvmeölçer uzun vadede güvenilir açı verir, ancak titreşimden etkilenir. Jiroskop kısa vadede pürüzsüzdür, fakat zamanla sürüklenir. Tam bir “biri iyi biri kötü” hikâyesi değil; ikisi birlikte daha güçlüdür.</p>

<table>
  <thead>
    <tr>
      <th>Sensör</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İvmeölçer</td>
      <td>Mutlak eğim referansı sağlar</td>
      <td>Motor titreşimlerine duyarlıdır</td>
    </tr>
    <tr>
      <td>Jiroskop</td>
      <td>Hızlı değişimleri iyi izler</td>
      <td>Entegrasyon hatası birikir</td>
    </tr>
    <tr>
      <td>Birleşik sonuç</td>
      <td>Kararlı ve hızlıdır</td>
      <td>Filtre ve ayar gerektirir</td>
    </tr>
  </tbody>
</table>

<p>Tamamlayıcı filtre şu şekilde kurulabilir:</p>

\[\theta_k = \alpha(\theta_{k-1} + \omega\Delta t) + (1-\alpha)\theta_{acc}\]

<p>Genellikle $\alpha$ değeri 0,95–0,99 arasında seçilir. Kontrol döngüsünün sabit zaman aralığında çalışması kritik önemdedir.</p>

<h2 id="pid-ile-denge-kontrolü">PID ile denge kontrolü</h2>

<p>PID denetleyici, hedef açı ile ölçülen açı arasındaki $e(t)$ hatasını motor komutuna dönüştürür:</p>

\[u(t)=K_p e(t)+K_i\int e(t)dt+K_d\frac{de(t)}{dt}\]

<p>$K_p$ robotu dik konuma iter, $K_d$ salınımı frenler, $K_i$ ise kalıcı küçük hataları giderir. Denge robotlarında integral terimi çoğunlukla çok düşük tutulur; aksi hâlde robot geçmiş hataları fazla ciddiye alıp dramatik bir kaçış gerçekleştirebilir.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">float</span> <span class="n">error</span> <span class="o">=</span> <span class="n">targetAngle</span> <span class="o">-</span> <span class="n">angle</span><span class="p">;</span>
<span class="n">integral</span> <span class="o">+=</span> <span class="n">error</span> <span class="o">*</span> <span class="n">dt</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">derivative</span> <span class="o">=</span> <span class="p">(</span><span class="n">error</span> <span class="o">-</span> <span class="n">previousError</span><span class="p">)</span> <span class="o">/</span> <span class="n">dt</span><span class="p">;</span>

<span class="kt">float</span> <span class="n">output</span> <span class="o">=</span> <span class="n">kp</span> <span class="o">*</span> <span class="n">error</span>
             <span class="o">+</span> <span class="n">ki</span> <span class="o">*</span> <span class="n">integral</span>
             <span class="o">+</span> <span class="n">kd</span> <span class="o">*</span> <span class="n">derivative</span><span class="p">;</span>

<span class="n">output</span> <span class="o">=</span> <span class="n">constrain</span><span class="p">(</span><span class="n">output</span><span class="p">,</span> <span class="o">-</span><span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">);</span>
<span class="n">setMotorPower</span><span class="p">(</span><span class="n">output</span><span class="p">);</span>
<span class="n">previousError</span> <span class="o">=</span> <span class="n">error</span><span class="p">;</span>
</code></pre></div></div>

<p>Bu kod her kontrol çevriminde açı hatasını hesaplar ve iki motora uygulanacak PWM değerini üretir. Robot çok hızlı titreşiyorsa $K_p$ veya $K_d$ yüksek olabilir. Yavaşça devriliyorsa $K_p$ yetersizdir. Sürekli bir tarafa gidiyorsa hedef açıya küçük bir ofset eklenebilir.</p>

<h2 id="sağlam-bir-geliştirme-sırası">Sağlam bir geliştirme sırası</h2>

<p>Önce motor yönlerini ve IMU eksenlerini doğrula. Ardından robotu kaldırarak açı ölçümünü seri portta izle. $K_i=0$ iken düşük $K_p$ ile başla, robot tepki verene kadar artır ve salınımı $K_d$ ile azalt. Enkoderlerden gelen hız bilgisini ikinci bir kontrol döngüsünde kullanmak, robotun dengede dururken odanın öbür ucuna kaçmasını önler.</p>

<p>İlk denemelerde robotu bir askı düzeneğinde çalıştırmak, motor çıkışını sınırlamak ve acil durdurma düğmesi eklemek iyi fikirdir. Başarılı sonuç yalnızca iyi PID ayarına değil; rijit şasiye, düşük mekanik boşluğa, temiz güç hattına ve hızlı örneklemeye bağlıdır. Ters sarkaç tam anlamıyla takım oyunudur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="robotik" /><category term="ters sarkaç" /><category term="pid" /><category term="arduino" /><category term="imu" /><category term="kontrol sistemleri" /><summary type="html"><![CDATA[İki tekerlek üzerinde duran bir robot, fizik kurallarına meydan okuyor gibi görünür. Oysa yaptığı şey düşmeyi engellemek değil, düşüşünü sürekli ölçüp tekerleklerini doğru yöne sürerek gövdesini yeniden dengelemektir. Bu proje; mekanik, elektronik, sensör füzyonu ve kontrol teorisini eğlenceli biçimde bir araya getirir.]]></summary></entry><entry><title type="html">ROS Mimarisine Giriş: Düğümler, Konular ve Servislerle Robotları Konuşturmak</title><link href="https://program.sonsuz.us/posts/ros-mimarisine-giris-dugumler-konular-ve-servislerle-robotlari-konusturmak/" rel="alternate" type="text/html" title="ROS Mimarisine Giriş: Düğümler, Konular ve Servislerle Robotları Konuşturmak" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ros-mimarisine-giris-dugumler-konular-ve-servislerle-robotlari-konusturmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/ros-mimarisine-giris-dugumler-konular-ve-servislerle-robotlari-konusturmak/"><![CDATA[<p>Bir robotun kamerası görüntü üretirken motorları hareket eder, sensörleri çevreyi ölçer ve karar mekanizması bütün bu verileri yorumlar. Tüm bileşenleri tek bir dev programda toplamak mümkün olsa da bakım yapmak kısa sürede kablo yumağı çözmeye dönüşür. ROS, yani Robot Operating System, robot yazılımını küçük ve bağımsız parçalara ayırarak bu karmaşayı yönetilebilir hâle getiren bir iletişim ve araçlar ekosistemidir.
``
ROS, adına rağmen geleneksel anlamda bir işletim sistemi değildir. Linux üzerinde çalışan; mesajlaşma, paket yönetimi, donanım soyutlama, görselleştirme ve hata ayıklama olanakları sunan bir ara katmandır. Bu yazıda modern projelerde yaygın olan <strong>ROS 2</strong> yaklaşımını temel alacağız.</p>

<h2 id="temel-fikir-hesaplama-grafiği">Temel fikir: Hesaplama grafiği</h2>

<p>ROS mimarisi, çalışan bileşenlerin ve aralarındaki bağlantıların oluşturduğu bir <strong>hesaplama grafiği</strong> olarak düşünülebilir. Grafikte düğümler yazılım bileşenlerini, bağlantılar ise veri akışını temsil eder:</p>

\[G = (V, E)\]

<p>Burada $V$ düğüm kümesi, $E$ ise düğümler arasındaki iletişim kanallarıdır. Örneğin kamera düğümünden görüntü işleme düğümüne doğru bir bağlantı bulunabilir. ROS 2, düğümlerin birbirini keşfetmesi ve haberleşmesi için çoğunlukla DDS tabanlı bir altyapı kullanır.</p>

<h2 id="düğümler-i̇ş-yapan-küçük-uzmanlar">Düğümler: İş yapan küçük uzmanlar</h2>

<p><strong>Düğüm (node)</strong>, belirli bir görevi yerine getiren çalışan süreç veya mantıksal bileşendir. Bir düğüm kamerayı okuyabilir, diğeri engel algılayabilir, başka biri motor komutu üretebilir. İyi tasarlanmış bir düğüm, tek bir sorumluluğa odaklanır.</p>

<p>Çalışan düğümleri görmek için:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ros2 node list
ros2 node info /kamera_dugumu
</code></pre></div></div>

<p>İkinci komut, ilgili düğümün yayınladığı ve dinlediği konuları, sunduğu servisleri ve diğer bağlantılarını gösterir. Böylece robotun görünmez iletişim ağı terminalde görünür olur.</p>

<h2 id="konular-sürekli-veri-akışı">Konular: Sürekli veri akışı</h2>

<p><strong>Konu (topic)</strong>, düğümler arasında asenkron veri taşır. Yayıncı düğüm mesaj gönderir; abone düğümler mesajları alır. Yayıncı, abonelerin kim olduğunu bilmek zorunda değildir. Bu gevşek bağlı yapı, bileşenlerin kolayca değiştirilmesini sağlar.</p>

<p>Örneğin bir LIDAR saniyede 10 tarama yayımlıyorsa frekans $f=10\,Hz$, iki mesaj arasındaki yaklaşık süre ise:</p>

\[T = \frac{1}{f} = 0.1\,s\]

<p>Basit bir ROS 2 Python yayıncısı şöyle yazılabilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">rclpy</span>
<span class="kn">from</span> <span class="n">rclpy.node</span> <span class="kn">import</span> <span class="n">Node</span>
<span class="kn">from</span> <span class="n">std_msgs.msg</span> <span class="kn">import</span> <span class="n">String</span>

<span class="k">class</span> <span class="nc">DurumYayincisi</span><span class="p">(</span><span class="n">Node</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="nf">super</span><span class="p">().</span><span class="nf">__init__</span><span class="p">(</span><span class="sh">'</span><span class="s">durum_yayincisi</span><span class="sh">'</span><span class="p">)</span>
        <span class="n">self</span><span class="p">.</span><span class="n">publisher</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="nf">create_publisher</span><span class="p">(</span><span class="n">String</span><span class="p">,</span> <span class="sh">'</span><span class="s">/robot_durumu</span><span class="sh">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
        <span class="n">self</span><span class="p">.</span><span class="nf">create_timer</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">self</span><span class="p">.</span><span class="n">durum_gonder</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">durum_gonder</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">mesaj</span> <span class="o">=</span> <span class="nc">String</span><span class="p">()</span>
        <span class="n">mesaj</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="sh">'</span><span class="s">Robot göreve hazır!</span><span class="sh">'</span>
        <span class="n">self</span><span class="p">.</span><span class="n">publisher</span><span class="p">.</span><span class="nf">publish</span><span class="p">(</span><span class="n">mesaj</span><span class="p">)</span>

<span class="n">rclpy</span><span class="p">.</span><span class="nf">init</span><span class="p">()</span>
<span class="n">rclpy</span><span class="p">.</span><span class="nf">spin</span><span class="p">(</span><span class="nc">DurumYayincisi</span><span class="p">())</span>
</code></pre></div></div>

<p>Kod, <code class="language-plaintext highlighter-rouge">/robot_durumu</code> konusuna saniyede bir metin mesajı yollar. <code class="language-plaintext highlighter-rouge">10</code> değeri, iletişimin QoS kuyruk derinliğini belirtir; yani geçici yoğunluklarda kaç mesajın saklanabileceğini etkiler.</p>

<h2 id="servisler-sor-ve-cevabı-bekle">Servisler: Sor ve cevabı bekle</h2>

<p><strong>Servis (service)</strong>, istek-cevap modelini kullanır. İstemci bir talep gönderir, sunucu işlemi gerçekleştirip tek bir yanıt döndürür. “Haritayı kaydet” veya “sensörü sıfırla” gibi seyrek ve sonucu beklenen işlemler için uygundur. Sürekli kamera görüntüsü taşımak için servis kullanmak ise postacıdan canlı yayın yapmasını istemeye benzer.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ros2 service list
ros2 service call /reset_sensor std_srvs/srv/Trigger
</code></pre></div></div>

<p>Bu komutlar servisleri listeler ve örnek bir sensör sıfırlama isteği gönderir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Konu</th>
      <th>Servis</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İletişim modeli</td>
      <td>Yayıncı-abone</td>
      <td>İstek-cevap</td>
    </tr>
    <tr>
      <td>Zamanlama</td>
      <td>Asenkron</td>
      <td>Genellikle senkron</td>
    </tr>
    <tr>
      <td>Alıcı sayısı</td>
      <td>Sıfır veya çok</td>
      <td>Belirli sunucu</td>
    </tr>
    <tr>
      <td>Uygun kullanım</td>
      <td>Sensör, hız, görüntü</td>
      <td>Sıfırlama, sorgulama</td>
    </tr>
    <tr>
      <td>Sürekli veri</td>
      <td>Çok uygun</td>
      <td>Uygun değil</td>
    </tr>
  </tbody>
</table>

<h2 id="hangisini-ne-zaman-seçmeli">Hangisini ne zaman seçmeli?</h2>

<p>Veri düzenli akıyor ve birden fazla bileşen tarafından tüketilebiliyorsa <strong>konu</strong> seçilir. İşlem belirli bir komutla başlayacak ve kısa sürede cevap verecekse <strong>servis</strong> daha uygundur. Uzun süren, geri bildirim ve iptal gerektiren navigasyon görevlerinde ise ROS 2’nin <strong>action</strong> yapısı tercih edilir.</p>

<p>Özetle düğümler robotun uzman çalışanları, konular ortak anons sistemi, servisler ise danışma masasıdır. Bu ayrımı doğru kurmak; ölçeklenebilir, test edilebilir ve parçaları yeniden kullanılabilir robot yazılımlarının temelini oluşturur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ros" /><category term="robotik" /><category term="python" /><category term="ros2" /><category term="düğümler" /><category term="konular" /><category term="servisler" /><summary type="html"><![CDATA[Bir robotun kamerası görüntü üretirken motorları hareket eder, sensörleri çevreyi ölçer ve karar mekanizması bütün bu verileri yorumlar. Tüm bileşenleri tek bir dev programda toplamak mümkün olsa da bakım yapmak kısa sürede kablo yumağı çözmeye dönüşür. ROS, yani Robot Operating System, robot yazılımını küçük ve bağımsız parçalara ayırarak bu karmaşayı yönetilebilir hâle getiren bir iletişim ve araçlar ekosistemidir.]]></summary></entry><entry><title type="html">SLAM Temelleri: Robotlar Bilmedikleri Ortamların Haritasını Nasıl Çıkarır?</title><link href="https://program.sonsuz.us/posts/slam-temelleri-robotlar-bilmedikleri-ortamlarin-haritasini-nasil-cikarir/" rel="alternate" type="text/html" title="SLAM Temelleri: Robotlar Bilmedikleri Ortamların Haritasını Nasıl Çıkarır?" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/slam-temelleri-robotlar-bilmedikleri-ortamlarin-haritasini-nasil-cikarir</id><content type="html" xml:base="https://program.sonsuz.us/posts/slam-temelleri-robotlar-bilmedikleri-ortamlarin-haritasini-nasil-cikarir/"><![CDATA[<p>Bir robotu daha önce hiç görmediği bir odaya bıraktığımızı düşünelim. Elinde mimari plan, GPS veya duvarların nerede olduğunu söyleyen sihirli bir pusula yok. Buna rağmen hem nerede bulunduğunu anlaması hem de çevresinin haritasını çıkarması gerekiyor. İşte <strong>SLAM</strong> (Simultaneous Localization and Mapping), yani <em>Eş Zamanlı Konumlandırma ve Haritalama</em>, bu tavuk-yumurta problemini çözmeye çalışır.</p>

<p>``</p>

<h2 id="slam-neden-zor-bir-problem">SLAM neden zor bir problem?</h2>

<p>Harita oluşturmak için robotun konumunu bilmesi gerekir. Konumunu doğru hesaplamak içinse çevresindeki noktaların haritadaki yerlerini bilmelidir. SLAM, bu iki bilinmeyeni sensör ölçümlerini zaman içinde birleştirerek birlikte tahmin eder.</p>

<p>Robotun $t$ anındaki durumu kabaca şöyle gösterilebilir:</p>

\[\mathbf{x}_t = [x_t, y_t, \theta_t]^T\]

<p>Burada $x_t$ ve $y_t$ robotun düzlemdeki konumunu, $\theta_t$ ise baktığı yönü belirtir. Amaç; kontrol girdileri $u_{1:t}$ ve sensör ölçümleri $z_{1:t}$ verildiğinde robotun rotasıyla haritayı birlikte bulmaktır:</p>

\[p(\mathbf{x}_{1:t}, m \mid z_{1:t}, u_{1:t})\]

<p>Buradaki $m$, bilinmeyen ortam haritasıdır. Denklem ürkütücü görünse de fikir basittir: Robot hareket eder, çevresini ölçer, tahminini düzeltir ve bunu sürekli tekrarlar.</p>

<h2 id="robot-çevresini-nasıl-algılar">Robot çevresini nasıl algılar?</h2>

<p>SLAM sistemlerinde tek bir kusursuz sensör yoktur. Her sensör farklı bir ipucu sağlar ve farklı biçimde hata yapar.</p>

<table>
  <thead>
    <tr>
      <th>Sensör</th>
      <th>Sağladığı bilgi</th>
      <th>Güçlü yanı</th>
      <th>Zayıf yanı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>LiDAR</td>
      <td>Nesnelere uzaklık</td>
      <td>Hassas geometri</td>
      <td>Maliyet ve yansıma sorunları</td>
    </tr>
    <tr>
      <td>Kamera</td>
      <td>Görsel özellikler</td>
      <td>Zengin çevre bilgisi</td>
      <td>Işık değişimlerinden etkilenir</td>
    </tr>
    <tr>
      <td>IMU</td>
      <td>İvme ve dönüş</td>
      <td>Çok hızlı ölçüm</td>
      <td>Hatası zamanla birikir</td>
    </tr>
    <tr>
      <td>Teker enkoderi</td>
      <td>Kat edilen mesafe</td>
      <td>Basit ve ucuz</td>
      <td>Kaygan zeminde şaşırır</td>
    </tr>
    <tr>
      <td>GPS</td>
      <td>Küresel konum</td>
      <td>Açık alanda kullanışlı</td>
      <td>Kapalı alanda çalışmaz</td>
    </tr>
  </tbody>
</table>

<p>Bu verilerin birleştirilmesine <strong>sensör füzyonu</strong> denir. Örneğin enkoder robotun bir metre ilerlediğini söylerken LiDAR, duvarın beklenenden yakın olduğunu gösterebilir. Algoritma her ölçümün belirsizliğini hesaba katarak daha güvenilir bir sonuç üretir.</p>

<h2 id="tahmin-ölçüm-ve-düzeltme-döngüsü">Tahmin, ölçüm ve düzeltme döngüsü</h2>

<p>SLAM’in kalbinde sürekli çalışan üç aşama bulunur:</p>

<ol>
  <li><strong>Hareket tahmini:</strong> Robotun motor komutlarına göre yeni konumu hesaplanır.</li>
  <li><strong>Ölçüm eşleştirme:</strong> Yeni sensör verileri, daha önce görülen özelliklerle karşılaştırılır.</li>
  <li><strong>Düzeltme:</strong> Tahmin ile ölçüm arasındaki fark azaltılır.</li>
</ol>

<p>Basitleştirilmiş bir konum güncellemesi Python ile şöyle modellenebilir:</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="k">def</span> <span class="nf">hareket_modeli</span><span class="p">(</span><span class="n">durum</span><span class="p">,</span> <span class="n">mesafe</span><span class="p">,</span> <span class="n">donus</span><span class="p">):</span>
    <span class="c1"># Önce robotun yönünü güncelle
</span>    <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">aci</span> <span class="o">=</span> <span class="n">durum</span>
    <span class="n">aci</span> <span class="o">+=</span> <span class="n">donus</span>

    <span class="c1"># Yeni yöne göre düzlemde ilerle
</span>    <span class="n">x</span> <span class="o">+=</span> <span class="n">mesafe</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="n">aci</span><span class="p">)</span>
    <span class="n">y</span> <span class="o">+=</span> <span class="n">mesafe</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="n">aci</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">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">aci</span><span class="p">])</span>

<span class="n">durum</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">])</span>
<span class="n">durum</span> <span class="o">=</span> <span class="nf">hareket_modeli</span><span class="p">(</span><span class="n">durum</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span> <span class="o">/</span> <span class="mi">4</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu kod yalnızca hareket tahmini yapar. Gerçek bir SLAM sistemi, sensör ölçümlerini kullanarak bu sonucu düzeltir; çünkü tekerlek kayması veya motor hataları robotu matematiksel rotasından uzaklaştırabilir.</p>

<h2 id="döngü-kapatma-ben-burayı-görmüştüm">Döngü kapatma: “Ben burayı görmüştüm!”</h2>

<p>Robot uzun süre ilerledikten sonra başlangıç noktasına dönebilir. Sistem daha önce gördüğü bir koridoru veya köşeyi tanırsa buna <strong>döngü kapatma</strong> denir. Bu keşif, biriken konum hatalarının tüm rota boyunca dağıtılarak düzeltilmesini sağlar. Aksi hâlde kare biçimindeki bir oda, haritada yamuk bir çokgene dönüşebilir.</p>

<p>SLAM çözümleri genellikle EKF-SLAM, parçacık filtreleri, grafik tabanlı SLAM veya görsel SLAM gibi yaklaşımlara ayrılır. Günümüzde robot süpürgelerden otonom otomobillere, dronlardan artırılmış gerçeklik uygulamalarına kadar pek çok sistem bu fikirlerden yararlanır. Kısacası robot, kusursuz biçimde “bilmez”; hareket eder, ölçer, şüphe duyar ve tahminini tekrar tekrar iyileştirir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="slam" /><category term="robotik" /><category term="haritalama" /><category term="lokalizasyon" /><category term="sensör füzyonu" /><category term="otonom sistemler" /><summary type="html"><![CDATA[Bir robotu daha önce hiç görmediği bir odaya bıraktığımızı düşünelim. Elinde mimari plan, GPS veya duvarların nerede olduğunu söyleyen sihirli bir pusula yok. Buna rağmen hem nerede bulunduğunu anlaması hem de çevresinin haritasını çıkarması gerekiyor. İşte SLAM (Simultaneous Localization and Mapping), yani Eş Zamanlı Konumlandırma ve Haritalama, bu tavuk-yumurta problemini çözmeye çalışır.]]></summary></entry><entry><title type="html">Sürü Robotiği: Basit Kurallardan Kolektif Zekâya</title><link href="https://program.sonsuz.us/posts/suru-robotigi-basit-kurallardan-kolektif-zekaya/" rel="alternate" type="text/html" title="Sürü Robotiği: Basit Kurallardan Kolektif Zekâya" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/suru-robotigi-basit-kurallardan-kolektif-zekaya</id><content type="html" xml:base="https://program.sonsuz.us/posts/suru-robotigi-basit-kurallardan-kolektif-zekaya/"><![CDATA[<p>Bir karınca tek başına yol planlama konusunda pek etkileyici görünmeyebilir; ancak binlerce karınca birlikte yiyeceğe giden verimli yollar oluşturabilir. Sürü robotiği de benzer bir fikirden beslenir: Çok sayıda görece basit robot, merkezi bir yönetici olmadan etkileşime girerek karmaşık görevleri tamamlar. İşin büyüsü, kolektif zekânın robotlara ayrı ayrı programlanmaması; yerel kuralların etkileşiminden kendiliğinden ortaya çıkmasıdır.</p>

<p>``</p>

<h2 id="sürü-robotiğinin-temel-fikri">Sürü robotiğinin temel fikri</h2>

<p>Geleneksel robot sistemlerinde kararları merkezi bir bilgisayar verebilir. Sürü yaklaşımında ise her robot yalnızca yakın çevresini algılar, komşularıyla sınırlı bilgi paylaşır ve birkaç basit kural uygular. Robotların hiçbiri sistemin tamamını görmek zorunda değildir.</p>

<p>Bu yapıya <strong>beliren davranış</strong> denir. Kuş sürülerinin aynı anda yön değiştirmesi, balıkların avcılardan kaçarken düzenli biçimde dağılması ve karıncaların feromon izleri oluşturması bunun doğal örnekleridir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Merkezi sistem</th>
      <th>Sürü sistemi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Karar verme</td>
      <td>Tek merkezde</td>
      <td>Robotlara dağıtılmış</td>
    </tr>
    <tr>
      <td>Arıza etkisi</td>
      <td>Kritik olabilir</td>
      <td>Genellikle yereldir</td>
    </tr>
    <tr>
      <td>Ölçeklenebilirlik</td>
      <td>Yönetimi zorlaşabilir</td>
      <td>Yeni robot eklemek kolaydır</td>
    </tr>
    <tr>
      <td>Robot karmaşıklığı</td>
      <td>Yüksek olabilir</td>
      <td>Görece düşüktür</td>
    </tr>
    <tr>
      <td>İletişim</td>
      <td>Küresel bilgi gerekebilir</td>
      <td>Yerel bilgi çoğu zaman yeterlidir</td>
    </tr>
  </tbody>
</table>

<h2 id="üç-basit-kural">Üç basit kural</h2>

<p>Birçok sürü hareketi üç davranışla modellenebilir:</p>

<ol>
  <li><strong>Ayrılma:</strong> Çarpışmayı önlemek için çok yakın komşulardan uzaklaş.</li>
  <li><strong>Hizalanma:</strong> Yakındaki robotların ortalama hareket yönüne yaklaş.</li>
  <li><strong>Birleşme:</strong> Komşuların oluşturduğu merkeze doğru ilerle.</li>
</ol>

<p>Bir robotun yeni hız vektörü şöyle ifade edilebilir:</p>

\[\vec{v}_{yeni} = w_s\vec{S} + w_a\vec{A} + w_c\vec{C}\]

<p>Burada $\vec{S}$ ayrılma, $\vec{A}$ hizalanma ve $\vec{C}$ birleşme vektörüdür. $w_s$, $w_a$ ve $w_c$ katsayıları ise davranışların önemini belirler. Ayrılma ağırlığı çok düşükse robotlar birbirine girer; çok yüksekse sürü, kalabalık bir asansörde kişisel alan arayan insanlara dönüşür.</p>

<h2 id="küçük-bir-python-modeli">Küçük bir Python modeli</h2>

<p>Aşağıdaki fonksiyon, tek bir robot için komşulara göre basitleştirilmiş yön değişimi hesaplar:</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="k">def</span> <span class="nf">suru_adimi</span><span class="p">(</span><span class="n">konum</span><span class="p">,</span> <span class="n">hiz</span><span class="p">,</span> <span class="n">komsu_konumlari</span><span class="p">,</span> <span class="n">komsu_hizlari</span><span class="p">):</span>
    <span class="k">if</span> <span class="nf">len</span><span class="p">(</span><span class="n">komsu_konumlari</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">hiz</span>

    <span class="n">merkez</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">(</span><span class="n">komsu_konumlari</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">ortalama_hiz</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">mean</span><span class="p">(</span><span class="n">komsu_hizlari</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">birlesme</span> <span class="o">=</span> <span class="n">merkez</span> <span class="o">-</span> <span class="n">konum</span>
    <span class="n">hizalanma</span> <span class="o">=</span> <span class="n">ortalama_hiz</span> <span class="o">-</span> <span class="n">hiz</span>

    <span class="n">farklar</span> <span class="o">=</span> <span class="n">konum</span> <span class="o">-</span> <span class="n">komsu_konumlari</span>
    <span class="n">mesafeler</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">norm</span><span class="p">(</span><span class="n">farklar</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">yakinlar</span> <span class="o">=</span> <span class="n">farklar</span><span class="p">[</span><span class="n">mesafeler</span> <span class="o">&lt;</span> <span class="mf">2.0</span><span class="p">]</span>
    <span class="n">ayrilma</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="n">yakinlar</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="k">if</span> <span class="nf">len</span><span class="p">(</span><span class="n">yakinlar</span><span class="p">)</span> <span class="k">else</span> <span class="n">np</span><span class="p">.</span><span class="nf">zeros</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

    <span class="n">yeni_hiz</span> <span class="o">=</span> <span class="n">hiz</span> <span class="o">+</span> <span class="mf">0.05</span> <span class="o">*</span> <span class="n">birlesme</span> <span class="o">+</span> <span class="mf">0.1</span> <span class="o">*</span> <span class="n">hizalanma</span> <span class="o">+</span> <span class="mf">0.3</span> <span class="o">*</span> <span class="n">ayrilma</span>
    <span class="n">maksimum_hiz</span> <span class="o">=</span> <span class="mf">2.0</span>
    <span class="n">norm</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">norm</span><span class="p">(</span><span class="n">yeni_hiz</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">norm</span> <span class="o">&gt;</span> <span class="n">maksimum_hiz</span><span class="p">:</span>
        <span class="n">yeni_hiz</span> <span class="o">=</span> <span class="n">yeni_hiz</span> <span class="o">/</span> <span class="n">norm</span> <span class="o">*</span> <span class="n">maksimum_hiz</span>

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

<p>Fonksiyon önce komşuların merkezini ve ortalama hızını bulur. İki birimden yakın robotlar için ayrılma kuvveti üretir, ardından üç davranışı farklı ağırlıklarla birleştirir. Son bölüm hızın fiziksel sınırı aşmasını engeller. Gerçek robotlarda buna sensör gürültüsü, gecikme, pil seviyesi ve engel algılama gibi değişkenler de eklenir.</p>

<h2 id="neden-dayanıklıdır">Neden dayanıklıdır?</h2>

<p>Sürüde görev bilgisi dağıtıldığı için tek bir robotun bozulması çoğunlukla tüm operasyonu durdurmaz. Eğer bir robotun çalışma olasılığı $p$ ve sürüdeki robot sayısı $N$ ise beklenen çalışan robot sayısı basitçe $Np$ olur. Sistem görevini yalnızca belirli sayıda robota ihtiyaç duyarak sürdürebiliyorsa doğal bir hata toleransı kazanır.</p>

<p>Bu özellik; afet bölgelerinde arama, tarım alanlarının izlenmesi, depo taşımacılığı, çevresel ölçüm ve uzay keşfi gibi alanlarda değerlidir. Yine de haberleşme çakışmaları, güvenlik açıkları ve beklenmeyen kolektif davranışlar önemli mühendislik sorunlarıdır.</p>

<p>Sürü robotiğinin en çarpıcı dersi şudur: Karmaşık sonuçlar için her zaman karmaşık bireyler gerekmez. Doğru seçilmiş birkaç yerel kural, yüzlerce robotu koordineli ve dayanıklı bir topluluğa dönüştürebilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="sürü robotiği" /><category term="robotik" /><category term="yapay zekâ" /><category term="kolektif davranış" /><category term="python" /><category term="algoritma" /><summary type="html"><![CDATA[Bir karınca tek başına yol planlama konusunda pek etkileyici görünmeyebilir; ancak binlerce karınca birlikte yiyeceğe giden verimli yollar oluşturabilir. Sürü robotiği de benzer bir fikirden beslenir: Çok sayıda görece basit robot, merkezi bir yönetici olmadan etkileşime girerek karmaşık görevleri tamamlar. İşin büyüsü, kolektif zekânın robotlara ayrı ayrı programlanmaması; yerel kuralların etkileşiminden kendiliğinden ortaya çıkmasıdır.]]></summary></entry><entry><title type="html">Ters Kinematik: Robot Koluna Hedefi Göster, Açıları O Bulsun</title><link href="https://program.sonsuz.us/posts/ters-kinematik-robot-koluna-hedefi-goster-acilari-o-bulsun/" rel="alternate" type="text/html" title="Ters Kinematik: Robot Koluna Hedefi Göster, Açıları O Bulsun" /><published>2026-09-16T00:00:00+00:00</published><updated>2026-09-16T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ters-kinematik-robot-koluna-hedefi-goster-acilari-o-bulsun</id><content type="html" xml:base="https://program.sonsuz.us/posts/ters-kinematik-robot-koluna-hedefi-goster-acilari-o-bulsun/"><![CDATA[<p>Bir robot koluna “şu noktaya uzan” demek kolaydır; asıl mesele, motorların bunu gerçekleştirmek için kaç derece dönmesi gerektiğini bulmaktır. Ters kinematik, hedef konumdan yola çıkarak eklem açılarını hesaplayan yöntemlerin genel adıdır. Endüstriyel robotlardan oyun karakterlerine kadar uzanan bu konu, geometri ile programlamanın keyifli bir buluşmasıdır.
``</p>
<h2 id="i̇leri-ve-ters-kinematik-farkı">İleri ve ters kinematik farkı</h2>

<p>Robot kolunun eklem açıları biliniyorsa uç noktanın konumunu hesaplamaya <strong>ileri kinematik</strong> denir. Ters kinematikte ise sonuç bilinir, bilinmeyenler aranır: Robot elinin ulaşması gereken hedef verilir ve uygun eklem açıları çözülür.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>İleri kinematik</th>
      <th>Ters kinematik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Girdi</td>
      <td>Eklem açıları</td>
      <td>Hedef konum ve yönelim</td>
    </tr>
    <tr>
      <td>Çıktı</td>
      <td>Uç nokta konumu</td>
      <td>Eklem açıları</td>
    </tr>
    <tr>
      <td>Çözüm yapısı</td>
      <td>Genellikle doğrudan</td>
      <td>Sıfır, bir veya birden fazla çözüm</td>
    </tr>
    <tr>
      <td>Zorluk</td>
      <td>Görece kolay</td>
      <td>Geometrik ve sayısal olarak zor</td>
    </tr>
    <tr>
      <td>Kullanım</td>
      <td>Simülasyon, konum bulma</td>
      <td>Hareket planlama, animasyon</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇ki-eklemli-düzlemsel-kol">İki eklemli düzlemsel kol</h2>

<p>Mantığı görmek için uzunlukları $L_1$ ve $L_2$ olan, düzlemde hareket eden iki parçalı bir kol düşünelim. Eklem açıları $\theta_1$ ve $\theta_2$ olsun. İleri kinematik denklemleri şöyledir:</p>

\[x=L_1\cos(\theta_1)+L_2\cos(\theta_1+\theta_2)\]

\[y=L_1\sin(\theta_1)+L_2\sin(\theta_1+\theta_2)\]

<p>Ters problemde $x$ ve $y$ hedefini bilir, açıları ararız. Önce kosinüs teoreminden ikinci eklemi hesaplarız:</p>

\[\cos(\theta_2)=\frac{x^2+y^2-L_1^2-L_2^2}{2L_1L_2}\]

<p>Ardından iki olası dirsek duruşundan biri seçilir:</p>

\[\theta_2=\operatorname{atan2}(\pm\sqrt{1-\cos^2(\theta_2)},\cos(\theta_2))\]

<p>Birinci eklem açısı ise şu ifadeyle bulunur:</p>

\[\theta_1=\operatorname{atan2}(y,x)-\operatorname{atan2}(L_2\sin\theta_2,L_1+L_2\cos\theta_2)\]

<p>$\pm$ işareti önemlidir: Aynı hedefe “dirsek yukarıda” veya “dirsek aşağıda” olmak üzere iki farklı duruşla ulaşılabilir. Yani robot bazen hedefe giderken küçük bir stil seçimi yapar!</p>

<h2 id="python-ile-geometrik-çözüm">Python ile geometrik çözüm</h2>

<p>Aşağıdaki fonksiyon, iki eklemli kol için iki muhtemel açı çiftini derece cinsinden döndürür. Hedef çalışma alanının dışındaysa hata üretir.</p>

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

<span class="k">def</span> <span class="nf">ters_kinematik</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">L1</span><span class="p">,</span> <span class="n">L2</span><span class="p">):</span>
    <span class="n">c2</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="o">*</span><span class="n">y</span> <span class="o">-</span> <span class="n">L1</span><span class="o">*</span><span class="n">L1</span> <span class="o">-</span> <span class="n">L2</span><span class="o">*</span><span class="n">L2</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">L1</span> <span class="o">*</span> <span class="n">L2</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&lt;=</span> <span class="n">c2</span> <span class="o">&lt;=</span> <span class="mi">1</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">Hedefe ulaşılamıyor</span><span class="sh">'</span><span class="p">)</span>

    <span class="n">cozumler</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">isaret</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span>
        <span class="n">s2</span> <span class="o">=</span> <span class="n">isaret</span> <span class="o">*</span> <span class="n">math</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="nf">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">c2</span><span class="o">*</span><span class="n">c2</span><span class="p">))</span>
        <span class="n">t2</span> <span class="o">=</span> <span class="n">math</span><span class="p">.</span><span class="nf">atan2</span><span class="p">(</span><span class="n">s2</span><span class="p">,</span> <span class="n">c2</span><span class="p">)</span>
        <span class="n">t1</span> <span class="o">=</span> <span class="n">math</span><span class="p">.</span><span class="nf">atan2</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span> <span class="o">-</span> <span class="n">math</span><span class="p">.</span><span class="nf">atan2</span><span class="p">(</span>
            <span class="n">L2</span> <span class="o">*</span> <span class="n">s2</span><span class="p">,</span> <span class="n">L1</span> <span class="o">+</span> <span class="n">L2</span> <span class="o">*</span> <span class="n">c2</span>
        <span class="p">)</span>
        <span class="n">cozumler</span><span class="p">.</span><span class="nf">append</span><span class="p">((</span><span class="n">math</span><span class="p">.</span><span class="nf">degrees</span><span class="p">(</span><span class="n">t1</span><span class="p">),</span> <span class="n">math</span><span class="p">.</span><span class="nf">degrees</span><span class="p">(</span><span class="n">t2</span><span class="p">)))</span>

    <span class="k">return</span> <span class="n">cozumler</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">ters_kinematik</span><span class="p">(</span><span class="mf">1.2</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">))</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">atan2</code>, sıradan arktanjanttan farklı olarak noktanın hangi bölgede bulunduğunu dikkate alır. <code class="language-plaintext highlighter-rouge">max</code> kullanımıysa kayan nokta hataları nedeniyle karekök içine çok küçük negatif bir değer girmesini önler.</p>

<h2 id="ulaşılabilirlik-ve-tekillikler">Ulaşılabilirlik ve tekillikler</h2>

<p>Hedef uzaklığı $r=\sqrt{x^2+y^2}$ ile gösterilirse hedef ancak şu koşulda erişilebilirdir:</p>

\[\vert L_1-L_2\vert \le r\le L_1+L_2\]

<p>Kol tamamen açıldığında veya kendi üzerine katlandığında <strong>tekillik</strong> oluşabilir. Bu durumlarda küçük bir hedef hareketi, eklemlerde çok büyük hızlar gerektirebilir.</p>

<p>Gerçek robotlarda üç boyut, eklem sınırları ve engeller devreye girdiği için analitik formüller her zaman yeterli olmaz. Jacobian tabanlı yöntemler, gradyan inişi ve CCD gibi sayısal algoritmalar hedefe adım adım yaklaşır. Başarılı bir ters kinematik sistemi yalnızca hedefe ulaşmamalı; güvenli, kararlı ve doğal görünen çözümü de seçmelidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ters kinematik" /><category term="robotik" /><category term="matematik" /><category term="python" /><category term="simülasyon" /><category term="kinematik" /><summary type="html"><![CDATA[Bir robot koluna “şu noktaya uzan” demek kolaydır; asıl mesele, motorların bunu gerçekleştirmek için kaç derece dönmesi gerektiğini bulmaktır. Ters kinematik, hedef konumdan yola çıkarak eklem açılarını hesaplayan yöntemlerin genel adıdır. Endüstriyel robotlardan oyun karakterlerine kadar uzanan bu konu, geometri ile programlamanın keyifli bir buluşmasıdır.]]></summary></entry></feed>