Flutter & Mobil İle İleri Düzey İvmeölçer Hareket Algılama Sistemi Nasıl Yapılır?

Flutter & Mobil İle İleri Düzey İvmeölçer Hareket Algılama Sistemi Nasıl Yapılır?
Flutter & Mobil İle İleri Düzey İvmeölçer Hareket Algılama Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce Flutter SDK sürümünüzün 3.20 ve üzeri olduğundan emin olmalısınız. Sensör verilerine erişmek için topluluk tarafından desteklenen ve performanslı çalışan sensors_plus paketini kullanacağız. Bu paket, cihazın donanım katmanıyla doğrudan iletişim kurarak ivmeölçer, jiroskop ve manyetometre verilerini sağlar.

Projenizin pubspec.yaml dosyasına gerekli bağımlılığı ekleyerek işe başlayın:

dependencies:
  flutter:
    sdk: flutter
  sensors_plus: ^6.0.0

Bağımlılığı ekledikten sonra terminalde flutter pub get komutunu çalıştırarak paketleri projenize dahil edin. İvmeölçer verileri saniyede onlarca kez güncellendiği için, bu verileri işlerken UI (arayüz) thread'ini yormamak adına verimli bir State Management (Durum Yönetimi) yaklaşımı benimsemeliyiz.

İvmeölçer Verilerini Okuma ve İşleme

İvmeölçer verileri, bir Stream (akış) üzerinden gelir. Bu akış, cihazın üç eksendeki anlık ivmesini AccelerometerEvent nesneleri olarak döner. İlk adım, bu akışı dinlemek ve verileri anlamlı bir yapıya dönüştürmektir.

import 'package:sensors_plus/sensors_plus.dart';

void listenAccelerometer() {
  accelerometerEvents.listen((AccelerometerEvent event) {
    double x = event.x;
    double y = event.y;
    double z = event.z;
    // Veriler burada işlenecek
    print("X: $x, Y: $y, Z: $z");
  });
}

Bu kod bloğu, sensörden gelen verileri konsola yazdırır. Ancak, ham veriler çok fazla "gürültü" içerir. Yani cihaz sabit dursa bile değerler sürekli 0.01 veya 0.02 gibi küçük sapmalar gösterir. Bu gürültüyü temizlemek için bir "Düşük Geçiren Filtre" (Low-Pass Filter) uygulamamız gerekecektir.

Hareket Algılama İçin Filtreleme Algoritması

Gürültüyü temizlemek için her yeni gelen veriyi, bir önceki verinin ağırlıklı ortalamasıyla birleştiren bir algoritma kullanırız. Bu, ani sıçramaları yok eder ve hareketin daha yumuşak bir grafik çizmesini sağlar.

double gravity = 9.8;
double alpha = 0.8; // Filtre katsayısı
double filteredX = 0;

void applyFilter(double rawX) {
  filteredX = alpha * filteredX + (1 - alpha) * rawX;
}

Buradaki alpha değeri, filtrenin ne kadar "sert" olacağını belirler. 0.8 değeri, ani hareketleri yakalamak ile gürültüyü engellemek arasında iyi bir denge sunar. Bu yöntemi X, Y ve Z eksenlerinin tamamına uygulayarak temiz bir sinyal elde edebilirsiniz.

Özel Hareket Kalıpları Tanımlama

Bir "sallama" (shake) hareketini algılamak için, ivmenin belirli bir eşik değerin üzerine çıkıp çıkmadığını kontrol etmeliyiz. Aşağıdaki örnek, cihazın şiddetli bir şekilde sallanıp sallanmadığını kontrol eden mantığı gösterir.

bool isShaking(AccelerometerEvent event) {
  double acceleration = event.x.abs() + event.y.abs() + event.z.abs();
  double threshold = 15.0; // Eşik değer
  
  if (acceleration > threshold) {
    return true;
  }
  return false;
}

Bu mantık, üç eksendeki toplam ivmeyi hesaplar. Eğer toplam ivme 15 m/s² değerini aşarsa, bir hareket algılandığına karar verilir. Bu eşik değerini cihazın hassasiyetine göre 12 ile 20 arasında ayarlayabilirsiniz.

Performans ve Bellek Yönetimi

Sensör akışları, uygulama arka plana alındığında bile çalışmaya devam edebilir ve bu da ciddi pil tüketimine yol açar. Bu yüzden, StatefulWidget yaşam döngüsünü kullanarak sensörü dispose etmeniz şarttır.

StreamSubscription? _streamSubscription;

@override
void dispose() {
  _streamSubscription?.cancel();
  super.dispose();
}

Bellek sızıntılarını (memory leaks) önlemek için StreamSubscription nesnesini her zaman kapatmalısınız. Ayrıca, verileri işlerken setState fonksiyonunu çok sık çağırmaktan kaçının; bunun yerine ValueNotifier veya StreamBuilder kullanarak sadece değişen widget'ları güncelleyin.

Yöntem Avantaj Dezavantaj
Ham Veri İşleme Anlık tepki Çok fazla gürültü
Düşük Geçiren Filtre Pürüzsüz veri Hafif gecikme
Eşik Değer (Threshold) Basit uygulama Yalancı pozitifler

Güvenlik Uyarısı: Kullanıcıdan sensör verilerini okumak için gerekli izinleri (iOS için Info.plist, Android için AndroidManifest.xml) aldığınızdan emin olun. Hassas verileri asla sunucuya doğrudan göndermeyin; verileri cihaz üzerinde işleyip sadece sonuçları (örneğin: "hareket algılandı") iletin.

Sıkça Sorulan Sorular

Sensör verileri neden sürekli değişiyor?

İvmeölçer, yerçekimini de ölçer. Cihaz tamamen hareketsiz olsa bile, yerçekimi ivmesi (yaklaşık 9.8 m/s²) Z ekseninde sürekli okunur. Bu bir hata değil, donanımın doğasıdır.

Uygulama arka plandayken sensör çalışır mı?

Varsayılan olarak Flutter sensörleri arka planda durdurur. Eğer arka planda veri toplamanız gerekiyorsa, flutter_background_service gibi ek paketler kullanarak servis yönetimi yapmanız gerekir.

Eşik değerini nasıl optimize ederim?

Farklı cihazların sensör kalitesi değişebilir. Kullanıcıya "hassasiyet ayarı" sunarak, eşik değerini (threshold) 10 ile 25 arasında değiştirebileceği bir slider eklemek en profesyonel yaklaşımdır.

Hangi sensör daha iyi: İvmeölçer mi Jiroskop mu?

İvmeölçer doğrusal hareketleri (hızlanma, düşme) ölçerken, jiroskop açısal dönüşleri (cihazın döndürülmesi) ölçer. Hareket algılama için genellikle ikisinin kombinasyonu kullanılır.

Veri işleme hızı (sampling rate) değiştirilebilir mi?

sensors_plus paketi varsayılan olarak işletim sisteminin belirlediği standart hızda veri gönderir. Çok yüksek hızlar pil tüketimini artırır, bu yüzden ihtiyacınız olandan daha hızlı veri almayın.

İleri Düzey Hata Ayıklama ve Veri Görselleştirme Teknikleri

Sensör verileriyle çalışırken en büyük zorluk, ham verideki gürültüyü çıplak gözle ayırt edememektir. Hareket algılama mantığınızı doğrulamak için verileri gerçek zamanlı olarak bir grafik üzerinde izlemek, mantıksal hataları (false-positive) tespit etmenizi kolaylaştırır. Flutter'da fl_chart gibi kütüphaneler kullanarak ivmeölçer verilerini anlık olarak çizebilirsiniz.

Hata ayıklama sürecinde şu adımları izlemeniz önerilir:

  • Veri Kaydı (Logging): Sensör verilerini bir CSV dosyasına veya yerel bir veritabanına kaydederek, hareket anındaki değerleri daha sonra analiz edin.
  • Gecikme Analizi: Stopwatch sınıfını kullanarak, sensör verisinin gelmesi ile işlenmesi arasındaki süreyi ölçün. 16ms'nin (60 FPS için) üzerindeki gecikmeler kullanıcı deneyimini düşürür.
  • Simülasyon: Fiziksel cihaz yerine, önceden kaydedilmiş sensör verilerini bir JSON dosyasından okuyarak uygulamanızın farklı hareket kalıplarına nasıl tepki verdiğini test edin.
// Basit bir performans ölçüm örneği
void processSensorData(AccelerometerEvent event) {
  final stopwatch = Stopwatch()..start();
  
  // Filtreleme ve analiz işlemleri
  applyLowPassFilter(event);
  
  stopwatch.stop();
  if (stopwatch.elapsedMilliseconds > 10) {
    debugPrint('Uyarı: İşlem süresi çok uzun: ${stopwatch.elapsedMilliseconds}ms');
  }
}

Üretim Ortamı İçin Deployment ve Kalibrasyon Stratejileri

Uygulamanızı mağazaya göndermeden önce farklı cihazların sensör hassasiyetlerinin birbirinden farklı olduğunu unutmamalısınız. Bazı giriş seviyesi cihazlarda ivmeölçer örnekleme hızı (sampling rate) kararsız olabilir. Bu durum, uygulamanızın belirli cihazlarda "çok hassas" veya "yetersiz" çalışmasına neden olur.

Deployment öncesi dikkat etmeniz gereken kritik noktalar şunlardır:

  1. Cihaz Bazlı Kalibrasyon: Kullanıcının cihazına özel bir kalibrasyon ekranı ekleyin. Kullanıcıdan cihazı sabit bir zemine koymasını isteyerek "sıfır noktası" (offset) değerlerini hesaplayın.
  2. Sensör Uyumluluk Kontrolü: Uygulamanın açılışında sensors_plus üzerinden sensörün kullanılabilirliğini kontrol edin ve desteklenmeyen cihazlarda kullanıcıyı bilgilendirin.
  3. Pil Optimizasyonu: Sensör dinleyicilerini onPause veya onDetached yaşam döngüsü metotlarında mutlaka iptal edin (cancel). Aksi takdirde uygulama arka planda pil tüketmeye devam edecektir.
Strateji Avantajı Risk
Dinamik Eşik Değeri Farklı cihazlara uyum sağlar Karmaşık kod yapısı
Sabit Eşik Değeri Düşük CPU kullanımı Cihazlar arası tutarsızlık

Son olarak, hareket algılama sisteminizi Unit Test ile desteklemek, algoritmanızda yaptığınız değişikliklerin mevcut hareket tanıma başarısını bozup bozmadığını anlamanızı sağlar. Özellikle Mock sensör verileri oluşturarak, algoritmanızın "sallama" veya "düşme" gibi senaryolarda beklenen sonucu verip vermediğini otomatikleştirin.

Sonuç

Flutter ile ivmeölçer tabanlı bir hareket algılama sistemi geliştirmek, temel matematiksel filtreleme ve doğru yaşam döngüsü yönetimi ile oldukça verimli sonuçlar verir. Bu rehberde öğrendiğiniz düşük geçiren filtre ve eşik değer mantığını kullanarak, kendi özel hareket tanıma kütüphanenizi oluşturabilirsiniz. Bir sonraki adım olarak, elde ettiğiniz bu verileri makine öğrenmesi modelleriyle (örneğin TensorFlow Lite) birleştirerek karmaşık hareketleri (yürüme, koşma, bisiklet sürme) sınıflandırmayı deneyebilirsiniz.

Kod güvenliği notu: Bu makaledeki kodlar eğitim amaçlıdır. Üretim ortamında sensör verilerini işlerken, kullanıcı gizliliğini korumak adına toplanan verilerin anonimleştirildiğinden ve sadece gerekli izinlerin alındığından emin olunuz.

Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıllık içerik üretimi deneyimiyle karmaşık süreçleri herkesin anlayabileceği basit adımlara dönüştürüyorum. Pratik ev çözümleri ve hayatı kolaylaştıran teknikler konusunda uzmanım.

Yorumlar (0)

Yorum Yaz