> Ana Sayfa > Yazılar

Yönlendirme Davranışları 2: Varış, Kovalama ve Kaçınma

Steering Behaviours 2: Arrive, Pursue and Evade
Bu yazımızda yönlendirme davranışları ile ilgili olarak varış, kovalama ve kaçınma davranışlarını inceleyeceğiz. Daha önceki yazımızda ajanımız hedefe doğru her zaman maksimum hızla hareket etmekteydi. Artık hedefe yaklaştıkça ajanımız yavaşlayacak ve hedeflediği noktaya yumuşak bir şekilde yaklaşıp duracak. Ayrıca, hareketli hedefleri daha verimli yakalamak ve kaçmak için hedefin gelecekteki olası konumunu nasıl tahmin edeceğimizi göreceğiz. Bu davranışları incelerken, ilk yazımdaki temel yönlendirme prensiplerine hakim olduğunuzu varsayacağım. Önceki yazımı okumadıysanız veya tekrar etmek isterseniz attaki linkten ulaşabilirsiniz.
page-logo
Yönlendirme Davranışları, Takip etmek ve Kaçma
Yönlendirme davranışı otonom ajanların hareketlerini kurgulamada kullandığımız bir araçtır. Otonom ajanların gerçekci hareket etmesi için yardımıyla çevresinde bulunan diğer objelerle etkileşim halinde ajanın kendisine kuvvet uygulamasıyla elde edilir. Bu işlemlerde vektöreleri bolca kullanacağız. Basit vektörel işlemler için hatılamak için 2 boyutlu vektöreleri anlattığım sayfayı ziyaret edebilirsiniz.

Varış Davranışı

Arrive Behaviour
Varış (Arrive) davranışı, bir önceki yazıda incelediğimiz "takip etme" (seek) davranışının daha farklı bir versiyonudur. Hatırlarsanız, "takip etme" (seek) davranışını kullanan bir ajan hedefe her zaman maksimum hızla ilerlediği için hedefi ıskalar ve etrafında salınım yapardı. Varış (Arrive) davranışı bu sorunu, hedefe yaklaştıkça ajanın hızını kademeli olarak azaltmasıyla çözer. Bu sayede ajan, hedef noktasına çarpmadan veya onu aşmadan, yumuşak bir frenlemeyle hassas bir şekilde ulaşır ve durur.
SembolAçıklamasıNot
VmaxV_{max}Ajanın maksiumum hızıGirdi
AmaxA_{max}Ajanın maksiumum ivmesiGirdi
TmaxT_{max}Ajanın maksiumum takip saniyesiGirdi
Pi\overrightarrow{P_{i}}Ajanın konumuGirdi
Pt\overrightarrow{P_{t}}Hedefin konumuGirdi
Vi\overrightarrow{V_{i}}Ajanın hızıGirdi
rdecr_{dec}Ajanın yavaşlama yarıçapıGirdi
Ve\overrightarrow{V_{e}}İstenen hızÇıktı
Ai\overrightarrow{A_{i}}Hesaplanan ivmeÇıktı
"Takip etme" (seek) davranışına ek olarak yavaşlama yarıçapı adlı parametre ekledik. Ajan bu yarıçapın içine girdiğinde yavaşlamaya başlayacak. Algoritma adımlarında daha detaylı inceleyeceğiz.

Algoritma Adımları

  1. Adım 1: İstenen hedefe doğru istenen hız hesaplama

    Hedefimizin konumundan ajanımızın konumunu çıkartarak ajanımızın istenen hızın doğrultusunu buluruz. Daha sonra elde ettiğimiz vektörün uzunluğunu maksimum hıza eşitleriz.

    PiPt=PtPi\overrightarrow{P{i}P{t}} = P{t} - P{i}
    Ve=normal(PiPt)Vmax\overrightarrow{V_{e}} = normal(\overrightarrow{P{i}P{t}}) * V{max}
  2. Adım 2: İstenen hızı mesefaye göre oranlamak

    Hedefle ajan arasındaki mesafe bulunur. Eğer mesafe yavaşlama yarıçapı içerindeyse istenen hız vektörü aynı oranda azaltılır.

    dtarget=len(PiPt)d_{target} = len(\overrightarrow{P{i}P{t}})
    Ve={Vedtarget>rdecVedtargetrdecdegilse;\overrightarrow{V_e}= \begin{cases} \overrightarrow{V_e} & d_{target} > r_{dec}\\ \overrightarrow{V_e} \frac{d_{target}}{r_{dec}} & \text{degilse;} \end{cases}
Bu algoritmayla birlikte ajan, hedefle arasındaki mesafeye göre yavaşlayacak. Böylece hedefe yaklaşıp yavaşça yumuşak bir şekilde duracak.
Yukarıdaki örnekte varış (arrive) ve takip etme (seek) arasındaki farkı görebilirsiniz. Takip etme davranışında ajanımız salınım yaparken varış (arrive) davranışında ajanımız hedefe yavaşça yaklaşarak durur. Varış (arrive) davranışı, takip etme (seek) davranışının bir modifikasyonu oludğu için her ikisinin kodunuda aşağıda paylaştım.
Takip etme (seek) davranışı:
            
        
Varış (arrive) davranışı:
            
        

Hareketli hedeflere varış

Durağan bir hedefe odaklanan standart varış algoritması, hedef hareket halindeyken beklendiği gibi çalışmaz. Çünkü bu algoritmada ajanın nihai hedefi, hızını sıfıra düşürerek durmaktır. Ancak hedef hareket etmeye devam ederse, hızını sıfırlayan bir ajan sürekli olarak hedefin gerisinde kalacak ve ona asla tam olarak "varamayacaktır".
Bu sorunu çözmek için algoritmada küçük ama etkili bir değişiklik yaparız: Ajanın hedef hızını sıfır olarak değil, hedefin kendi hızı olarak belirleriz.
Bu yeni yaklaşımda ajan, hedefe yaklaştıkça yavaşlayarak durmak yerine, kendi hızını ve yönünü hedefin hızı ve yönüyle eşitlemeye çalışır. Yavaşlama yarıçapına girdiğinde, istenen hız artık sıfıra doğru değil, hedefin mevcut hızına doğru yumuşak bir geçiş yapar. Sonuç olarak ajan, hedefin yanında durmak yerine onunla birlikte aynı hızda hareket etmeye başlar, bu da çok daha doğal ve başarılı bir takip davranışı sağlar.
SembolAçıklamasıNot
VmaxV_{max}Ajanın maksiumum hızıGirdi
AmaxA_{max}Ajanın maksiumum ivmesiGirdi
TmaxT_{max}Ajanın maksiumum takip saniyesiGirdi
Pi\overrightarrow{P_{i}}Ajanın konumuGirdi
Pt\overrightarrow{P_{t}}Hedefin konumuGirdi
Vi\overrightarrow{V_{i}}Ajanın hızıGirdi
Vt\overrightarrow{V_{t}}Hedefin hızıGirdi
rdecr_{dec}Ajanın yavaşlama yarıçapıGirdi
Ve\overrightarrow{V_{e}}İstenen hızÇıktı
Ai\overrightarrow{A_{i}}Hesaplanan ivmeÇıktı
Hesaplamamıza varış (arrive) davranışına ek olarak hedefin hızınıda ekledik. Artık varış (arrive) davranışında kullandığımız algoritmada sadece 2. adımı değiştirmemiz yeterli.

Algoritma Adımları

  1. Adım 2: İstenen hızı mesefaye göre oranlamak

    Bu adımda, ajan yavaşlama yarıçapına girdiğinde, istenen hızı durağan bir hedefteki gibi sıfıra çekmek yerine, hedefin kendi hızına doğru mesafeyle orantılı olarak yaklaştırırız. Bunu, iki hız arasında yumuşak bir geçiş (interpolasyon) yaparak sağlarız

    Ve={Vedtarget>rdecVt(1dtargetrdec)+Vedtargetrdecdeg˘ilse;\overrightarrow{V_e}= \begin{cases} \overrightarrow{V_e} & d_{target} > r_{dec}\\ \overrightarrow{V_t} * (1 - \frac{d_{target}}{r_{dec}}) + \overrightarrow{V_e} * \frac{d_{target}}{r_{dec}} & \text{değilse;} \end{cases}
    Bu formül, ajan hedeften uzakken istenen hızı hedefe yönelik maksimum hıza yakın tutar. Ajan hedefe yaklaştıkça, hedefin kendi hızının ağırlığı artar ve tam varış anında istenen hız, hedefin hızıyla eşitlenir. Bu, ajanın hedefle bütünleşerek akıcı bir şekilde birlikte hareket etmesini sağlar.
Yukarıdaki simülasyonun da gösterdiği gibi, durağan hedefler için tasarlanmış varış (arrive) davranışı, hareketli hedeflerde yetersiz kalır. Ajanın son hızını sıfıra indirme hedefi, onun sürekli olarak hedefin gerisinde kalmasına yol açar. Buna karşılık, ajanın nihai hızını hedefin mevcut hızıyla eşitlemesi, çok daha etkili bir sonuç doğurur. Bu küçük değişiklik, ajanın hedefi sadece yakalamasını değil, aynı zamanda onunla birlikte akıcı bir şekilde hareket etmesini sağlar.
            
        
Bu iki davranışın temel farkı, ajanın hedefe ne kadar hassas bir şekilde ve hangi hızda ulaşması gerektiğidir. Takip etme (Seek) davranışı, ajanın hedefi en kısa sürede yakalamasının önemli olduğu durumlar için idealdir. Ajan, hedefe her zaman maksimum hızla hareket eder ve hedefi geçebilir. Bu nedenle, bir oyun karakterinin kaçan bir düşmanı kovalaması veya bir arama aracının geniş bir bölgedeki bir noktaya hızla ulaşması gibi senaryolarda seek davranışı kullanılır
Bunun aksine, varış (arrive) davranışı, ajanın hedef noktasına yumuşak, kontrollü ve tam isabetle varması gerektiği durumlar için tasarlanmıştır. Bir araç simülasyonunda aracın durması gereken park yerine yavaşça yanaşması, bir robot kolun üretim bandındaki belirli bir noktaya hassas bir şekilde ulaşması veya bir oyun karakterinin bir diyalog penceresinin önünde durması gibi senaryolarda arrive davranışı tercih edilir. Özetle, seek hız ve genel yönelime odaklanırken, arrive kesinlik ve zarif bir duruş sağlar.

Kovalama Davranışı

Pursue Behaviour
Kovalama (Pursue) davranışı, takip etme (seek) davranışının hareketli hedefler için geliştirilmiş bir versiyonudur. Bilindiği gibi, basit takip etme davranışında ajanımız hedefin mevcut konumuna doğru maksimum hızla ilerler ve bu durum, hedef hareketliyse onu yakalamayı imkansız hale getirebilir. Kovalama (Pursue) davranışı ise bu sorunu çözmek için hedefin hızını ve kendi hızını hesaba katarak gelecekteki olası konumunu tahmin eder. Bu sayede ajan, hedefin peşinden gitmek yerine, onun rotasını keserek daha verimli ve akıllı bir şekilde hedefe ulaşır.
Öncelikle kullanacağımız değişkenleri yazalım.
SembolAçıklamasıNot
VmaxV_{max}Ajanın maksiumum hızıGirdi
AmaxA_{max}Ajanın maksiumum ivmesiGirdi
TmaxT_{max}Ajanın maksiumum takip saniyesiGirdi
Pi\overrightarrow{P_{i}}Ajanın konumuGirdi
Pt\overrightarrow{P_{t}}Hedefin konumuGirdi
Vi\overrightarrow{V_{i}}Ajanın hızıGirdi
Vt\overrightarrow{V_{t}}Hedefin hızıGirdi
ttTahmin saniyesiAra değişken
Ptpredic\overrightarrow{P_{t_{predic}}}Ajanın tahmini konumuAra değişken
Ve\overrightarrow{V_{e}}İstenen hızÇıktı
Ai\overrightarrow{A_{i}}Hesaplanan ivmeÇıktı
pursue behaviour

Algoritma Adımları

  1. Adım 1: Hedefe Tahmini Ulaşma Süresi Hesaplanır.

    Ajanın hedefe varması için gereken süreyi, aralarındaki mesafeyi ajanın mevcut hızına bölerek tahmin ederiz. Ancak, hedefin çok uzakta olduğu durumlarda bu sürenin aşırı büyümesini engellemek için, hesaplanan bu süreyi önceden belirlenmiş bir maksimum tahmin süresi (T_max) ile sınırlar ve hangisi daha küçükse onu kullanırız. Bu hesap tam olarak doğru olmayabilir ama ajanımız her adımda kendi kendini düzelteceğinden yeterli olacaktır.

    PiPt=PtPi\overrightarrow{P{i}P{t}} = \overrightarrow{P{t}} - \overrightarrow{P{i}}
    t=min(Tmax,len(PiPt)len(Vi))t = min(T_{max}, \frac{len(\overrightarrow{P{i}P{t}})}{len(\overrightarrow{V_i)}})
  2. Adım 2: Hedefin tahmini konuöu hesaplanır

    Hedefe ulaşma süresini hesapladık. Bu süre sonunda hedefin nerede olacağını bulmak için hedefin mevcut konumuna hedefin hızını bu süre ile çarparak ekleriz.

    Ptpredic=Pt+Vtt\overrightarrow{P_{t_{predic}}} = \overrightarrow{P_t} + \overrightarrow{V_t} * t
  3. Adım 3: Ajanımızın İstenen hızı hesaplanır

    Tahmini hedefden ajanımızın konumunu çıkartarak istenen hız vektörünü buluruz.

    PiPtpredic=PtpredicPi\overrightarrow{P_iP_{t_{predic}}} = \overrightarrow{P_{t_{predic}}} - \overrightarrow{P_i}
    Ve=normal(PiPtpredic)Vmax\overrightarrow{V_{e}} = normal(\overrightarrow{P_iP_{t_{predic}}}) * V_{max}
Yukarıdaki örnek, iki davranış arasındaki zekâ farkını ortaya koyuyor. Takip Etme davranışı, hedefin mevcut konumuna tepki verdiği için sürekli bir adım geride kalır ve hedefle arasındaki mesafeyi kapatamaz. Kovalama (pursue) davranışı ise proaktif bir hamle yapar; hedefin gelecekteki konumunu öngörerek rotasını keser ve bu sayede hedefi kolayca yakalar.
Kovalama (pursue) davranışı:
            
        
Takip Etme (Seek), hedefin mevcut konumuna yöneldiği için en basit ve en hızlı yöntemdir. Bu, durağan hedeflere (örneğin, haritada tıklanan bir noktaya gitmek) veya ajanın hedeften çok daha hızlı olduğu ve basit bir takibin yeterli olduğu durumlar için mükemmeldir. Ancak, hedef hareketliyse ve hızı ajanınkine yakınsa, Seek davranışı ajanın hedefin arkasında çaresizce sürüklenmesine neden olabilir.
Kovalama (Pursue) ise bu noktada devreye girer. Hedefin gelecekteki konumunu tahmin ederek, ajanın daha zeki ve proaktif bir rota çizmesini sağlar. Bu, özellikle bir düşman karakterin oyuncunun yolunu kesmesi veya bir avcının kaçan avını yakalaması gibi daha gerçekçi ve verimli takip senaryoları için idealdir.

Kaçınma Davranışı

Evade Behaviour
Kaçınma (Evade) davranışı, bir önceki yazıda incelediğimiz kaçma (flee) davranışının daha akıllı bir versiyonudur. Basit Kaçma (flee) davranışında ajan, tehlikenin mevcut konumundan dosdoğru kaçarken, bu durum hareketli bir tehlike karşısında etkisiz kalabilir. Kaçınma (Evade) davranışı ise, tıpkı Kovalama (Pursue) davranışında olduğu gibi, tehlikenin gelecekteki olası konumunu tahmin eder. Bu sayede ajan, tehlikenin üzerine doğru gelmek yerine onun rotasından çekilerek çok daha etkili bir şekilde kaçmayı başarır.
Öncelikle kullanacağımız değişkenleri yazalım.
SembolAçıklamasıNot
VmaxV_{max}Ajanın maksiumum hızıGirdi
AmaxA_{max}Ajanın maksiumum ivmesiGirdi
TmaxT_{max}Ajanın maksiumum takip saniyesiGirdi
Pi\overrightarrow{P_{i}}Ajanın konumuGirdi
Pt\overrightarrow{P_{t}}Tehlikenin konumuGirdi
Vi\overrightarrow{V_{i}}Ajanın hızıGirdi
Vt\overrightarrow{V_{t}}Tehlikenin hızıGirdi
ttTahmin saniyesiAra değişken
Ptpredic\overrightarrow{P_{t_{predic}}}Hedefin tahmini konumuAra değişken
Ve\overrightarrow{V_{e}}İstenen hızÇıktı
Ai\overrightarrow{A_{i}}Hesaplanan ivmeÇıktı
pursue behaviour

Algoritma Adımları

  1. Adım 1: Tehlikenin Tahmini Süresi Hesaplanır.

    Bu adımda, ajanın tehlikeden kaçması için ne kadar ilerisini görmesi gerektiğini hesaplarız. Bunu, ajan ile tehlike arasındaki mesafeyi ajanın mevcut hızına bölerek bir tahmin süresi (t) bularak yaparız. Bu sürenin çok büyümesini engellemek için, sonucu önceden belirlenmiş bir maksimum tahmin süresi (T_max) ile sınırlar ve en küçük olan değeri kullanırız.

    PiPt=PtPi\overrightarrow{P{i}P{t}} = \overrightarrow{P{t}} - \overrightarrow{P{i}}
    t=min(Tmax,len(PiPt)len(Vi))t = min(T_{max}, \frac{len(\overrightarrow{P{i}P{t}})}{len(\overrightarrow{V_i)}})
  2. Adım 2: Tehlikenin Tahmini Konumu Hesaplanır

    Bir önceki adımda hesapladığımız tahmin süresini (t) kullanarak, tehlikenin o süre sonunda nerede olacağını öngörürüz. Bu tahmini konum tehlikenin mevcut konumuna, hızıyla t süresinin çarpımının eklenmesiyle bulunur. Artık kaçmamız gereken asıl nokta burasıdır.

    Ptpredic=Pt+Vtt\overrightarrow{P_{t_{predic}}} = \overrightarrow{P_t} + \overrightarrow{V_t} * t
  3. Adım 3: Ajanımızın İstenen hızı hesaplanır

    Artık kaçmamız gereken tahmini noktayı bildiğimize göre, bu adımdan sonrası Kaçma (Flee) davranışı ile aynıdır. Ajanın mevcut konumundan, tehlikenin tahmini konumunu çıkartarak bir kaçış yönü belirleriz. Bu yön vektörünün uzunluğunu ajanın maksimum hızına (V_max) eşitleyerek istenen kaçış hızı vektörünü elde ederiz.

    PtpredicPi=PiPtpredic\overrightarrow{P_{t_{predic}P_i}} = \overrightarrow{P_i} - \overrightarrow{P_{t_{predic}}}
    Ve=normal(PtpredicPi)Vmax\overrightarrow{V_{e}} = normal(\overrightarrow{P_{t_{predic}P_i}}) * V_{max}
Yukarıdaki interaktif örnek, iki kaçış davranışı arasındaki zekâ ve verimlilik farkını net bir şekilde sergiliyor. Soldaki kaçma (flee) davranışını kullanan ajan, tehlikenin sadece o anki konumuna tepki verir. Bu durum, onu tehlikenin hareket yönünü hesaba katmadan, içgüdüsel bir şekilde dosdoğru uzağa iter. Sonuç olarak, özellikle tehlike ajanın rotasını kesecek şekilde hareket ediyorsa, ajan etkili bir şekilde kaçamaz.
Sağdaki kaçınma (evade) davranışı ise proaktif bir yaklaşım sergiler. Tehlikenin gelecekteki konumunu tahmin ederek, onun rotasından tamamen çekilecek en akıllıca kaçış yolunu seçer. Bu öngörü, ajanın tehlikeyle kesişme riskini ortadan kaldırır ve çok daha güvenli ve verimli bir kaçış sağlar. Özetle, kaçmak (flee) anlık bir tepki iken, kaçınmak (evade) akıllı bir öngörüdür.
            
        
Kovalama (Pursue) davranışının aksine, kaçınma (evade) davranışı her senaryoda basit kaçma (flee) davranışından daha üstün değildir. Aralarındaki seçim, tehlikenin doğasına ve ajanınızdan beklediğiniz davranış türüne bağlıdır. Bu iki davranış arasındaki kararı verirken aşağıdaki noktaları göz önünde bulundurmak gerekir:

Ne Zaman Kaçma (Flee) Kullanılmalı?

  • Doğrudan Gelen Tehditler Eğer tehlike doğrudan ajanın üzerine doğru geliyorsa, tehlikenin gelecekteki konumu zaten ajanın tam arkasında olacaktır. Bu durumda Evade'in yapacağı tahmin, Flee'nin basit kaçış yönünden pek farklı olmaz. Bu senaryoda Evade kullanmak gereksiz bir hesaplama yükü getirir.
  • Yeterince hızlı ajan Ajan, tehlikeyi mevcut hızı ve hızlanma kapasitesi ile kolayca geride bırakabiliyorsa, basit kaçış etkili olacaktır.
  • "Panik" Hissi Yaratmak Eğer bir ajanın stratejik düşünmeden, içgüdüsel bir panikle kaçmasını istiyorsanız, Flee bu davranışı daha doğal bir şekilde yansıtır

Ne Zaman Kaçınma (Evade) Kullanılmalı?

  • Kesişen Rotalar ve Mermiler Kaçınmanın en büyük avantajı, tehlikenin ajanın önünden geçtiği (doğrudan üzerine gelmediği) durumlarda ortaya çıkar. Örneğin, bir mermiden veya yandan geçen bir düşmandan kaçarken, kaçmak (flee) ajanı tehlikenin arkasına doğru kaçırarak onu tehlikenin rotası üzerinde tutabilir. Kaçınmak ise merminin gelecekteki konumunu tahmin ederek ajanı rotanın tamamen dışına, en güvenli noktaya yönlendirir.
  • Akıllı Davranış Gereksinimi Eğer ajanın (örneğin önemli bir NPC veya ana karakterin yardımcısı) zeki ve taktiksel davrandığını göstermek istiyorsanız, kaçınmak bu izlenimi çok daha iyi verir.

Kinematik Varış Davranışı

Kinematic Arrive Behaviour
Temel varış (Arrive) davranışında, ajanın yavaşlamaya başlayacağı yarıçapı manuel olarak belirleriz. Ancak bu sabit değer, ajanın hızına göre yetersiz kalabilir veya gereksiz yere erken frenlemeye neden olabilir. Kinematik varış(kinematic arrive) davranışı, bu sorunu çözmek için devreye girer. Ajanın mevcut hızını ve maksimum ivmesini kullanarak, durması için gereken en uygun yavaşlama yarıçapını otomatik olarak hesaplar. Bu sayede, ajan hızına bağlı olarak her zaman en doğru mesafede frenlemeye başlar ve yumuşak bir varış gerçekleştirir.
Bu otomatik hesaplamanın mantığını anlamak için en basit senaryoyu düşünelim: Ajanımızın hızı tam olarak hedefe doğruyken. Bu ideal durumda, ajanımız sadece durmaya odaklanarak hedefe varabilir. Hız ve ivmenin temel fizik prensiplerini kullanarak, bu senaryoda ajanın mevcut hızını tamamen sıfırlaması için gereken durma mesafesini hesaplayabiliriz. Bu mesafe, bizim otomatik olarak belirlediğimiz durma yarıçapımız olacaktır. Ajan bu yarıçapa girdiğinde, maksimum ivmesini kullanarak duracak ve hedefe en hızlı şekilde, tam isabetle varacaktır.
Yukarıdaki simülasyonda gördüğümüz bu ideal senaryo, ajanın hız vektörünün tam olarak hedefe dönük olduğu varsayımına dayanır. Ancak gerçekte bu her zaman gerçekleşmez; ajan genellikle hedefe bir açıyla yaklaşır. Bu durumda, sadece durmaya odaklanmak yeterli olmaz, ajanın aynı zamanda yönünü de hedefe doğru çevirmesi gerekir. İşte bu sorunu çözmek için, durma yarıçapı'na ek olarak bir de düzeltme yarıçapı (r_corr) tanımlarız. Bu yeni yarıçap, ajana hem yönünü düzeltmesi hem de durması için yeterli zamanı ve mesafeyi tanıyan daha geniş bir "manevra alanı" sağlar.
Yukarıdaki interaktif örnek, kinematik varış(kinematic arrive) davranışının iki temel yarıçapını görselleştiriyor. Kırmızı kesikli çizgi, ajanın yönü hedefe hizalıyken durması için gereken minimum mesafeyi, yani durma yarıçapını (r_stop) temsil eder. Turuncu kesikli çizgi ise, ajanın hedefe yönelik olmayan hızını düzeltmek için ihtiyaç duyduğu ekstra mesafeyi de içeren, daha geniş olan düzeltme yarıçapını (r_corr) gösterir.
Algoritmaya geçmeden önce daha önceki davranışlarda yaptığımız gibi değişkenleri tanıyalım.
SembolAçıklamasıNot
VmaxV_{max}Ajanın maksiumum hızıGirdi
AmaxA_{max}Ajanın maksiumum ivmesiGirdi
Pi\overrightarrow{P_{i}}Ajanın konumuGirdi
Pt\overrightarrow{P_{t}}Hedefin konumuGirdi
Vi\overrightarrow{V_{i}}Ajanın hızıGirdi
Vi\overrightarrow{V_{i\parallel}}Ajanın hedefe doğrultusuna paralel hızıAra değişken
V\overrightarrow{V_{\perp}}Ajanın hedef doğrultusuna dik hızıAra değişken
Vt\overrightarrow{V_{t}}Hedefin hızıGirdi
rcorr\overrightarrow{r_{corr}}Ajanın düzeltme yarıçapıAra değişken
tcorrt_{corr}Ajanın düzeltme süresiAra değişken
tcorrt_{corr}Ajanın düzeltme süresiAra değişken
rstop\overrightarrow{r_{stop}}Ajanın durma yarıçapıAra değişken
tstopt_{stop}Ajanın durma süresiAra değişken
Ai\overrightarrow{A_{i}}Hesaplanan ivmeÇıktı

Algoritma Adımları

  1. Adım 1: Durma süresi hesaplanır.

    Varma davranışımızdan farklı olarak burada durma yarıçapını manuel olarak ayarlamayacağız. Kullanacağımız formül ajanımızın mevcut hızını kaç saniyede durabileceğini hesaplamak.

    Tistop=len(Vi)/AmaxT_{i-stop} = len(\overrightarrow{V{i}})/ A_{max}
  2. Adım 2: Durma yarıçapı bulunur.

    Süremizi bulduk. Bu süre boyunca ajanımızın ne kadar mesafe kat edeceğini hesaplayacağız.

    rstop=12len(Vi)Tistopr_{stop} = \frac{1}{2} * len(\overrightarrow{V{i}}) * T_{i-stop}
  3. Adım 3: Düzeltme süresi hesaplanır.

    Ajanımız bu mesafede iken sadece doğrultusunu hedefe yönlendirmeye çalışacak. Bunun için ajanımızın hızını, hedefle olan doğrultusuna göre izdüşümünü alacağız. Hedefimiz elde ettiğimiz vektörün ajanımızın durma yarıçapına gireceği hız yapmak.

    PiPt=PtPi\overrightarrow{P_iP_t} = \overrightarrow{P_t} - \overrightarrow{P_i}Vi=proj(Vi,PiPt)\overrightarrow{V_{i\parallel}} = proj(\overrightarrow{V_i}, \overrightarrow{P_iP_t})

    Durma yarıçapına gireceği hız vektörünü bulduk. Mevcut hızdan çıkartırsak elimine etmek istediğimiz hızı buluruz.

    V=ViVi\overrightarrow{V_{\perp}} = \overrightarrow{V_i} - \overrightarrow{V_{i\parallel}}

    Elimine etmemiz gereken hızı bulduk. Bunu ne kadar sürede yapabileceğimizi hesaplayacağız. Bunun içinde yine maksimum ivmeyi kullanacağız.

    ticorr=len(V)/Amaxt_{i-corr} = len(\overrightarrow{V_{\perp}}) / A_{max}
  4. Adım 4: Düzeltme mesafesi bulunur.

    Düzeltme yarıçapı (r_corr), ajanın güvenli bir şekilde durabilmesi için gereken r_stop mesafesi ile ajanın yönünü hedefe çevirirken kat edeceği mesafenin toplamıdır. Bu ek mesafeyi, ajanın hedefe yönelik paralel hızı ile bu yönü düzeltmesi için gereken düzeltme süresini (T_i-corr) çarparak buluruz. Bu, ajanın "dönerken ne kadar ilerleyeceğini" hesaba katmamızı sağlar ve böylece düzeltme mesafesini doğru bir şekilde belirlemiş oluruz.

    rcorr=rstop+len(V)Ticorrr_{corr} = r_{stop} + len(\overrightarrow{V_{\parallel}}) * T_{i-corr}
  5. Adım 5: İstenen hız hesaplana

    Ajanımız 3 farklı davranış gerçekleştirebilir. Her biri için istenen hız hesaplama farklı olacaktır.

    Ve={Ve1dtarget<rstopVe2dtarget<rcorrVe3deg˘ilse; \overrightarrow{V_e}= \begin{cases} \overrightarrow{V_{e1}} & d_{target} < r_{stop}\\ \overrightarrow{V_{e2}} & d_{target} < r_{corr}\\ \overrightarrow{V_{e3}} & \text{değilse;} \end{cases}

    Eğer ajanımız durma yarıçapının içinde ise ajanımızının istenen hızı sıfır olacak.

    Ve1=0\overrightarrow{V_{e1}} = 0

    Eğer ajanımız durma yarıçapının dışında ama düzeltme yarıçapının içinde ise doğrultusunu hedefe doğru yönlendirecek.

    Ve2=Vi=proj(Vi,PiPt)\overrightarrow{V_{e2}} = \overrightarrow{V_{i\parallel}} = proj(\overrightarrow{V_i}, \overrightarrow{P_iP_t})

    Eğer ajanımız düzeltme yarıçapının da dışında ise maksimum ivme ile hedefe yönlenecek.

    Ve3=Vmaxnormal(PiPt)\overrightarrow{V_{e3}} = V_{max} * normal(\overrightarrow{P_iP_t})
Tüm bu adımlar bir araya geldiğinde, ajanın her durumda en uygun mesafede yavaşlamasını sağlayan sağlam bir mantık oluşturur. Teoride incelediğimiz bu adımların, şimdi de pratikteki koda dökülmüş haline bakalım.
            
        
Bu iki varış (arrive) davranışı da ajanın hedefe yumuşak bir şekilde ulaşmasını sağlasa da, aralarındaki seçim projenizin gereksinimlerine, yani basitlik ve kontrol ile gerçekçilik ve esneklik arasındaki dengeye bağlıdır.

Ne Zaman Standart Varış (Arrive) Davranışı Seçilmeli?

  • Basitlik ve Hız Gerektiğinde Hızlı bir şekilde prototip oluşturmanız veya basit bir "hedefe git ve dur" mantığına ihtiyacınız olduğunda en kolay ve en performanslı çözümdür.
  • Ajan Hızları Sabit Olduğunda Eğer ajanlarınızın maksimum hızı oyun boyunca değişmiyorsa, tek bir yarıçap değeri ayarlayarak istediğiniz sonuca kolayca ulaşabilirsiniz.
  • Çok Sayıda Ajan Varsa Bir RTS oyunundaki yüzlerce birim veya basit kalabalık simülasyonları gibi, her bir ajanın hesaplama maliyetinin önemli olduğu durumlarda Arrive'ın sadeliği büyük bir avantajdır.

Ne Zaman Kinematik Varış (Kinematic Arrive) Davranışı Seçilmeli?

Kinematik Arrive davranışı, yavaşlama ve düzeltme yarıçaplarını ajanın o anki hızına ve maksimum ivmesine göre dinamik olarak hesaplar. Bu, onu daha karmaşık ama çok daha güçlü bir araç yapar. Şu durumlarda tercih edilmelidir:
  • Gerçekçilik ve Hassasiyet Öncelikliyse: Bir araba simülasyonu, bir robot kolu veya fiziksel olarak doğru hareket etmesi gereken herhangi bir ajan için kinematik varış (kinematic arrive), çok daha inandırıcı sonuçlar verir.
  • Ajan Hızları Değişken Olduğunda: Ajanınız bir hız artışı (boost) alabiliyor veya farklı zeminlerde hızı değişiyorsa, kinematik varış (kinematic arrive) bu yeni hıza anında adapte olarak her zaman en uygun mesafede fren yapmasını sağlar.
  • "Sihirli Sayılardan" Kaçınmak İstendiğinde Her ajan türü için tek tek "en iyi" yavaşlama yarıçapını bulmakla uğraşmak yerine, ajanın fiziksel özelliklerini (A_max) bir kez tanımlayıp gerisini algoritmanın halletmesini istediğinizde bu yöntem hayat kurtarır.

Kinematik Kovalama Davranışı

Kinematic Pursue Behaviour
Bir önceki Kovalama (Pursue) davranışında, ajanın hedefe ulaşma süresini basit bir tahminle hesaplayarak hedefin muhtemel konumunu bulmuştuk. Bu yaklaşım birçok durumda yeterli olsa da, mükemmel bir kesişim noktası sunmaz. Şimdi ise bu basit mantığı bir adım ileri taşıyarak, ajanın hedefi yakalayabileceği en uygun kesişim noktasını kinematik denklemler kullanarak çok daha hassas bir şekilde nasıl hesaplayabileceğimizi göreceğiz.
Bu davranışın temel amacı, hem hedefin hem de ajanın mevcut hareket vektörlerini kullanarak, gelecekteki rotalarının kesişeceği tam noktayı ve bu kesişimin ne kadar süre sonra gerçekleşeceğini matematiksel olarak hesaplamaktır. Bu hesaplamayı yaparken, ajanın kesişim noktasına doğru sabit bir doğrultuda, yani düz bir çizgi üzerinde ilerleyeceğini varsayarız. Dolayısıyla, çözmemiz gereken problem, ajanın bu düz çizgi üzerinde hedefini yakalamasını sağlayacak olan o başlangıç hız vektörünü bulmaktır.
SembolAçıklamasıNot
VmaxV_{max}Ajanın maksiumum hızıGirdi
AmaxA_{max}Ajanın maksiumum ivmesiGirdi
Pi\overrightarrow{P_{i}}Ajanın konumuGirdi
Pt\overrightarrow{P_{t}}Hedefin konumuGirdi
Vi\overrightarrow{V_{i}}Ajanın hızıGirdi
Vt\overrightarrow{V_{t}}Hedefin hızıGirdi
TmaxT_{max}Maksimum kesişim süresiGirdi
ttKesişim süresiAra değişken
Ppred\overrightarrow{P_{pred}}Hesaplanan kesişim noktasıAra değişken
Ve\overrightarrow{V_{e}}Ajanın istenen hızıÇıktı
Ai\overrightarrow{A_{i}}Hesaplanan ivmeÇıktı

Algoritma Adımları

  1. Adım 1: Kesişim denklemini oluşturmak

    Bu davranışın temelinde, ajan ile hedefin t saniye sonra aynı noktada buluşacağı varsayımı yatar. İlk olarak, hedefin t saniye sonraki konumunu basit bir formülle ifade edebiliriz

    Ptfut=Pt+Vtcurt\overrightarrow{P_{t-fut}} = \overrightarrow{P_{t}} + \overrightarrow{V{t-cur}} * t

    Ajanın da aynı t süresi içinde bu gelecekteki konuma ulaşması gerekir. Bu, ajanın kat etmesi gereken mesafenin, kendi hızıyla bu sürenin çarpımına eşit olduğu anlamına gelir. Bu ilişkiyi tek bir denklemde birleştirebiliriz:

    Vit=(Pt+Vtt)Pi\overrightarrow{V_{i}} * t = (\overrightarrow{P_{t}} + \overrightarrow{V_{t}} * t) - \overrightarrow{P_{i}}

    Ancak bu vektörel denklemde iki bilinmeyenimiz var: kesişim süresi ve ajanın gitmesi gereken yön. Denklemi çözebilmek için bir varsayım daha yapmamız gerekir: Ajan, hedefi en kısa sürede yakalamak için her zaman maksimum hızıyla (V_max) hareket edecektir. Bu varsayımı denkleme dahil edip, vektörleri skaler değerlere (uzunluklarına) çevirdiğimizde, denklem tek bilinmeyenli ve çözülebilir bir hale gelir

    len(Vmax)t=len(PiPt+Vtt)len(\overrightarrow{V_{max}}) * t = len(\overrightarrow{P_{i}P_{t}} + \overrightarrow{V_{t}} * t)
  2. Adım 2: Kesişim denklemini standart forma dönüştürmek

    Önceki adımda elde ettiğimiz denklem, uzunluk fonksiyonu içerdiği için doğrudan çözülemez. Bu sorunu aşmak için denklemin her iki tarafının karesini alarak işe başlarız. Bu, vektörlerin uzunlukları yerine, kendileriyle olan noktasasal çarpımlarını kullanmamızı sağlar.

    (Vmaxt)2=len(PiPt+Vtt)2(V_{max} * t)^2 = len(\overrightarrow{P_{i}P_{t}} + \overrightarrow{V_{t}} * t)^2Vmax2t2=(PiPt+Vtt)(PiPt+Vtt)V_{max}^2 * t^2 = (\overrightarrow{P_iP_t} + \overrightarrow{V_t} * t) * (\overrightarrow{P_iP_t} + \overrightarrow{V_t} * t)Vmax2t2=PiPt2+2(PiPtVt)+(VtVt)t2V_{max}^2 * t^2 = |\overrightarrow{P_iP_t}|^2 + 2*(\overrightarrow{P_iP_t} \cdot \overrightarrow{V_t}) + (\overrightarrow{V_t} \cdot \overrightarrow{V_t}) * t^2
    Bu açılımı tamamladıktan sonra, amacımız denklemi çözebilmek için t'nin kuvvetlerine göre yeniden düzenlemektir. Tüm terimleri bir tarafa toplayarak, denklemi bildiğimiz ikinci dereceden standart forma (at² + bt + c = 0) getiririz.
    at2+bt+c=0a * t^2 + b * t + c = 0(Vmax2(VtVt))t22(PiPtVt)tPiPt2=0(V_{max}^2 - (\overrightarrow{V_t} \cdot \overrightarrow{V_t})) * t^2 - 2 * (\overrightarrow{P_iP_t} \cdot \overrightarrow{V_t}) \cdot t - |\overrightarrow{P_iP_t}|^2 = 0

    Bu düzenlenmiş denklemden, a, b ve c katsayılarının neye karşılık geldiğini artık net bir şekilde görebiliriz.

    a=Vmax2Vt2a = V_{max}^2 - |\overrightarrow{V_t}|^2b=2PiPtVtb = -2 * \overrightarrow{P_iP_t} \cdot \overrightarrow{V_t}c=PiPt2c = -|\overrightarrow{P_iP_t}|^2
  3. Adım 3: Kesişim denkleminin çözümü

    Artık standart formdaki denklemimizin a, b ve c katsayılarını bildiğimize göre, denklemi çözerek kesişim süresini (t) bulabiliriz. İkinci dereceden bir denklemi çözerken ilk adım, diskriminantı (delta, ∇) hesaplamaktır.
    =b24ac\nabla = b^2 - 4 a c
    Diskriminantın değeri, bize kesişimin mümkün olup olmadığı hakkında kritik bir bilgi verir.
    Eğer ∇ < 0 ise: Denklemin gerçek bir çözümü yoktur. Bu, ajanın mevcut hızıyla hedefi asla yakalayamayacağı anlamına gelir. Bu durumda, en iyi strateji olarak basit Takip Etme (Seek) davranışına geri döneriz.
    Eğer ∇ ≥ 0 ise: Denklemin bir veya iki gerçek çözümü vardır, yani kesişim mümkündür.
    Bu çözümleri standart formülü kullanarak bulabiliriz:
    t=b±2at = \frac{-b \pm \sqrt{\nabla}}{2a}
    Bu formül bize iki olası zaman değeri verebilir. Fiziksel olarak anlamlı olan çözüm, gelecekteki bir zamanı temsil eden en küçük pozitif t değeridir. Hesaplanan bu t değerini, isteğe bağlı olarak belirlediğimiz bir maksimum tahmin süresi (T_max) ile sınırlayarak son kesişim süremizi elde ederiz.
    t=min(t,Tmax)t = min(t,T_{max})
  4. Adım 4: Kesişimin noktasını bulmak

    Süremizi belirlediğimize göre artık tek yapmamız gereken kesişim noktasını bulmak. Bunun hedefin mevcut hızı ile kesişim süresi sonrasında nerede olduğunu bulmak.
    Ppred=Pt+Vtt\overrightarrow{P_{pred}} = \overrightarrow{P_{t}} + \overrightarrow{V_{t}} * t
  5. Adım 5: İstenen hızı bulmak

    Ajanımızın istenen hızı kesişim noktasına doğru maksimum hızı olacaktır.
    PiPpred=PpredPi\overrightarrow{P_{i}P_{pred}} = \overrightarrow{P_{pred}} - \overrightarrow{P_{i}}Vexp=Vmaxnormal(PiPpred)\overrightarrow{V_{exp}} = V_max * normal(\overrightarrow{P_{i}P_{pred}})
Yukarıdaki interaktif örnek, kinematik kovalama (kinematic pursue) davranışının nasıl çalıştığını net bir şekilde gösteriyor. Simülasyon, hedefin mevcut rotasını (kesikli çizgi), ajanın mevcut konumunu (mor daire) ve nerede kesişeceğini (turuncu kare) hesaplıyor. Bu sayede ajan, hedefin peşinden gitmek yerine, rotasını keserek onu en verimli şekilde yakalamayı amaçlar.
            
        
Her iki kovalama (pursue) davranışı da ajanın hareketli bir hedefi yakalamasını amaçlasa da, aralarındaki seçim basit ve etkili bir tahmin ile matematiksel olarak kusursuz bir kesişim arasındaki dengeye bağlıdır.

Ne Zaman Standart Kovalama (Pursue) Davranışı Seçilmeli?

  • Genel Amaçlı Kullanım: Oyun yapay zekalarının %90'ı için bu davranış yeterlidir. Hızlıdır, uygulaması kolaydır ve genellikle inandırıcı bir "hedefin önüne geçme" hissi yaratır.
  • Performans Öncelikliyse: Sahnede bu davranışı kullanan çok sayıda ajanınız varsa, Pursue'un daha düşük hesaplama maliyeti, karmaşık ikinci dereceden denklem çözümüne göre büyük bir avantaj sağlar.
  • Hedef Sık Yön Değiştiriyorsa: Eğer hedef sürekli olarak manevra yapıyorsa, kinematik kovalamanın hesapladığı "mükemmel" kesişim noktası bir sonraki anda geçersiz kalabilir. Standart kovalamanın sürekli olarak basit ve hızlı düzeltmeler yapması, bu tür kararsız hedeflere karşı daha akıcı bir takip sağlayabilir.

Ne Zaman Kinematik Kovalama Davranışı Seçilmeli?

  • Hassasiyet ve Mükemmellik Gerektiğinde: Yavaş ilerleyen mermiler veya belirli bir gecikmeyle etkinleşen yetenekler gibi, anlık olmayan saldırılar tasarlarken bu yöntem kritik öneme sahiptir. Ajanın saldırısının hedefin rotasıyla tam olarak nerede ve ne zaman kesişeceğini hassas bir şekilde hesaplayarak, en verimli şekilde tam isabet sağlamak için kullanılır.
  • "Akıllı" Yapay Zeka Gösterimi: Ajanın ne kadar zeki ve hesaplamalı hareket ettiğini oyuncuya göstermek istediğinizde (örneğin bir boss dövüşünde veya özel bir yetenekte), bu davranış bariz bir şekilde daha "akıllı" görünür.
  • Hedefin Rotası Tahmin Edilebilir Olduğunda: Bu davranış, hedefin en azından kısa bir süre için mevcut hız vektörünü koruyacağı varsayımına dayanır. Bu varsayımın geçerli olduğu durumlarda (örneğin, bir gezegenin yörüngesine giren bir gemi veya düz bir yolda ilerleyen bir araç), en etkili sonuçları verir.

Sonuç

Bu yazıda, daha önce anlattığımız 2 temel davranışın üzerine katarak, 5 yeni davranışı detaylı bir şekilde inceledik. Arkaplanda yatan matematiksel prensipleri kullanarak, karmaşık hareketleri nasıl simüle edebileceğimizi gördük. Varış (Arrive) davranışında, ajanın hedefe yumuşak bir şekilde yaklaşmasını sağlarken, kinematik varış (kinematic arrive) ile bu süreci ajanın mevcut hızına ve ivmesine göre dinamik olarak ayarladık. Kovalama (Pursue) davranışında ise, hareketli hedefleri akıllı takip etmenin iki farklı yolunu keşfettik: basit bir tahminle hızlı ve etkili bir takip sağlarken, kinematik kovalama (kinematic pursue) ile matematiksel olarak en doğru kesişim noktasını hesapladık. Son olarak, kaçınma (evade) davranışı ile ajanın tehlikenin gelecekteki konumunu tahmin ederek, basit Kaçma davranışından daha etkili bir şekilde uzaklaşmasını sağladık.