Arduino – Kalman Filtresi Uygulaması

KALMAN FİLTRESİ NEDİR?

Kalman filtresi modellenmiş bir sistemin bir önceki verilerine göre ilerisini tahmin eden bir filtredir. Bir filtreden daha çok bir tahmin yöntemi gibi düşünülebilir. Eş zamanlı olarak kullanılabilen bu filtrenin kullandığı algoritma sayesinde sisteme tanımlanan gürültü ve hata modellemeleri ile çok başarılı sonuçlar elde edilebilir. Her sistem için geçerli bir formülü yoktur bu yüzden elinizdeki sisteme göre bir model oluşturup bu modele göre parametreleri belirleyip bu prametrelere göre algoritmayı oluşturmanız gerekir. Veri sayısı arttıkça yapılan tahmin de kuvvetlenecektir. Bu özelliği onu diğer filtrelerden ayırmaktadır. Rudolf Kalman tarafından geliştirilen bu filtre 1960’lı yıllarda Apollo Uzay programı dahil olmak üzere bir çok alanda kullanılmıştır. Kimilerine göre 20. yüzyılın en büyük buluşlarından biridir.

Peki bu filtre Arduino ile ne için kullanılabilir?

IoT sistemlerin giderek yaygınlaşmaya başladığı bir gerçektir. Bu sistemlerde sensörler büyük yer tutmaktadır. Sadece IoT sitemlerde değil bir çok açıdan Arduino veya diğer mikrodenetleyiciler ile sensör okuma işlemi yapılmaktadır. Bu sensörlerden okunan veriler içinde bir takım gürültüler barındırır. Bu sensörler dijital çıkış verenler olabileceği gibi analog sensörler de olabilir. Bu sensörlerden gelen verilerdeki gürültürü filtrelemek ve içinden gerçek istenen verileri elde edebilmek için Kalman filtresi oldukça kullanışlıdır. Aynı zamanda 8-Bit mikrodenetleyicilere de rahatlıkla uygulanabilmektedir.

Kalman Matematiği

Kalman filtresini en basit şekilde yazacak olursak:

  • Xk = Hesaplanan kalman değeri
  • Kk = Kalman Kazancı
  • Zk = Ölçüm sonucu elde edilen değer
  • Xk(k-1) = Bir önceki hesaplanan Kalman değeri

Burada Kk değeri dışındaki değerler bilinen değerlerdir. Peki Kalman Kazancı yani “Kalman Gain” nedir? Kalman Kazancı Kalman filtresinin en büyüleyici yanı diyebiliriz. Örneğin burada Kk 0.5 gibi bir değer seçilirse filtremiz ortalama alan bir fonksiyona dönüşmüş olacaktır. Bu da Kalman filtresinin en büyük özelliğinden feragat etmemiz anlamına gelir. Peki ne yapacağız? Sistemimizi modelledikten sonra her defasında yeniden hesaplanan bir Kk değeri tanımayacağız. İşler buradan sonra biraz karışacak gibi görünse de önemli kısım burası. Modele bakmanın artık zamanı geldi:

Burada w(k-1) önceki işlemin; vk ise ölçülen işlemin gürültüsüdür. Uk kontrol sinyalidir ve bir çok uygulamada kullanılmaz. Burada anlatılmak istenen her hesaplanan değer aslında bir önceki değere, kontrol sinyaline ve bir önceki gürültü değerinin toplamından oluşurken ölçülen değer de bu değerle birlikte yeni gürültünün toplamıdır. Burada önemli kısım A, B ve H parametreleridir. Matris katsayıları olmalarına rağmen çoğu zaman nümerik olarak bulunurlar. Burada w(k-1) ve vk gauss gürültüsü olarak alınabilirler. Bu yöntem doğadaki bir çok gürültüyü modellemek için oldukça sık kullanılan bir yöntemdir.

Kalman filtresinin uygulamasında iki aşama mevcuttur. Bunlar tahmin ve düzeltmedir. Bu iki aşama aynı zaman diliminde yani “k” değerinde hesaplanır (Her k değeri için). Formülleri ise şu şekildedir:

Hata kovaryansı Kalman Kazancını hesaplamak için kullanılan bir değerdir. Elde edilen değerlerden bağımsız olarak güncellenir. Sistemin modellemesi sırasında belirlenen R ve Q değerleri ile hesaplanır.

  • Q>R durumu modelde hatanın daha baskın olduğu durumda;
  • R>Q durumu ölçümlerde hatanın daha baskın olduğu durumda;
  • Q=R durumu ise hangisinin baskın olduğunun bilinmediği durumlarda kullanılır.

A,B ve H Değerleri: Arduino ile sensör verisi okumak için genel anlamda bir model oluşturalım. Kontrol sinyalimiz olmadığı için “uk” sıfır olacaktır bu yüzden B değerinin bir önemi kalmamaktadır. H değeri ise karşılaşacağınız bir çok durumda “1” olacaktır.  A değeri ise çoğu bir boyutlu sistemlerde “1” değerini almaktadır. Bu değerler şimdilik işimizi görecektir. Formüllerin son hali ise şu şekilde olacaktır:

 

Arduino ile Kalman Filtresi

Arduino yapmış olduğumuz ölçümler üzerinde filtre sonuçlarını göstermeden önce Arudino için yazmış olduğumuz koda göz atalım:

*Kodların herkes tarafından anlaşılması için İngilizce tanımlamalar yapılmıştır. Burada R ve Q değerleri deneme yanılma ile bulunmuştur. Elinizdeki ölçümler için değiştirmeniz gerekebilir.

Fonksiyon sadece bir girdi ile işlem yapmaktadır. Yani sadece yapmış olduğunuz ölçümü vermeniz sonucunda size çıktıyı verecektir. Sistemi düzgün modellemeniz durumunda sonuçlar sizi memnun edecektir. İvme sensörü ile yaptığımız testlerin sonuçları şu şekildedir:

SONUÇLAR

Kullanılan ivmeölçer -16000 ila 16000 arası değer vermektedir. Yapılan testlerde saniyede 100 örnek alınmış ve sensör hızlı bir şekilde X ekseni üzerinde döndürülmüştür. Elde edilen sonuçlar X ekseninin sonuçlarıdır. Ölçüm değerlerinden bazıları (-16000) – (160000) aralığında olmamakla birlikte çoğu zaman gürültülüdür. Kalman filtresi ise büyük ölçüde sinyali düzeltmiştir.

Sonuç-1 : Test 1.3 Saniye Sürmüştür – 130 Değer

Sonuç-2 : Test 1.4 Saniye Sürmüştür – 140 Değer

Sonuç-3 : Test 1.3 Saniye Sürmüştür – 130 Değer

Sonuç-4 : Test 4.4 Saniye Sürmüştür – 440 Değer

Sonuçlarda da görüldüğü üzere Kalman filtresi bir çok durumda istenmeyen sinyallerden kurtulmuş, gürültüyü azaltmış ve daha doğru sonuçlar vermiştir. Daha karışık sistemlerde sistemin doğru modellenmesi durumunda yüksek doğrulukta sonuçlar verecektir. Arduino ile sensör okuma yaptığınız projelerinizde rahatlıkla kullanabilirsiniz. İyi Eğlenceler!

Filtrelerle ilgileniyorsanız Arduino ile Hareketli Ortalamalar Yazımıza da bakabilirsiniz.!

FAYDALANILAN KAYNAKLAR:

Kaynak 1

Kaynak 2

Kaynak 3

“Arduino – Kalman Filtresi Uygulaması” Hakkında 6 Yorum

  1. Merhabalar,
    Başlangıçta fonksiyonun çalışması için
    Default kalman_old=?; cov_old=?; ne olmalıdır?
    Emeğiniz için teşekkür eder iyi çalışmalar dilerim.

  2. Merhabalar bir sorum olacak;
    kovaryans değerini, seçilen eksen için o andaki high ve low değerlerin ortalaması olarak anlıyorum. Ben bu high ve low değerleri registerdan byte fonksiyonu ile okuyorum. Bunların ortalamasını almak için decimal değere nasıl çeviriyoruz acaba? Ya da yanlışım varsada bir yardımcı olur musunuz?

    1. Tam olarak ne yaptığını anlayamadım. Instagram hesabımızdan ayrıntılı olarak yazabilir misiniz?

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.