Saya bekerja dengan data GPS, mendapatkan nilai setiap detik dan menampilkan posisi saat ini di peta. Masalahnya adalah bahwa kadang-kadang (khususnya ketika akurasi rendah) nilainya sangat bervariasi, membuat posisi saat ini untuk "melompat" antara titik-titik yang jauh di peta.
Saya bertanya-tanya tentang beberapa metode yang cukup mudah untuk menghindari ini. Sebagai ide pertama, saya berpikir untuk membuang nilai-nilai dengan akurasi di luar batas tertentu, tetapi saya kira ada beberapa cara lain yang lebih baik untuk dilakukan. Apa cara yang biasa dilakukan oleh program?
Jawaban:
Berikut adalah filter Kalman sederhana yang dapat digunakan untuk situasi ini. Itu berasal dari beberapa pekerjaan yang saya lakukan pada perangkat Android.
Teori filter General Kalman adalah semua tentang estimasi untuk vektor, dengan akurasi estimasi diwakili oleh matriks kovarians. Namun, untuk memperkirakan lokasi pada perangkat Android teori umum dikurangi menjadi kasus yang sangat sederhana. Penyedia lokasi Android memberikan lokasi sebagai garis lintang dan bujur, bersama dengan keakuratan yang ditentukan sebagai angka tunggal yang diukur dalam meter. Ini berarti bahwa alih-alih matriks kovarians, akurasi dalam filter Kalman dapat diukur dengan angka tunggal, meskipun lokasi dalam filter Kalman diukur dengan dua angka. Juga fakta bahwa garis lintang, bujur dan meter secara efektif semua unit yang berbeda dapat diabaikan, karena jika Anda memasukkan faktor penskalaan ke dalam filter Kalman untuk mengubahnya semuanya menjadi unit yang sama,
Kode dapat ditingkatkan, karena mengasumsikan bahwa perkiraan terbaik dari lokasi saat ini adalah lokasi terakhir yang diketahui, dan jika seseorang bergerak, mungkin saja menggunakan sensor Android untuk menghasilkan perkiraan yang lebih baik. Kode memiliki satu parameter bebas Q, dinyatakan dalam meter per detik, yang menggambarkan seberapa cepat akurasi meluruh tanpa adanya perkiraan lokasi baru. Parameter Q yang lebih tinggi berarti bahwa akurasi meluruh lebih cepat. Filter Kalman umumnya bekerja lebih baik ketika akurasi meluruh sedikit lebih cepat daripada yang mungkin diharapkan, jadi untuk berjalan-jalan dengan ponsel Android saya menemukan bahwa Q = 3 meter per detik berfungsi dengan baik, meskipun saya biasanya berjalan lebih lambat dari itu. Tetapi jika bepergian dengan mobil cepat, jumlah yang jauh lebih besar harus digunakan.
sumber
Q_metres_per_second
sesuai dengan variabelsigma
di bagian "Proses terkait" di artikel Wikipedia itu.Q_metres_per_second
adalah standar deviasi dan diukur dalam meter, jadi meter dan bukan meter / detik adalah unitnya. Ini sesuai dengan standar deviasi distribusi setelah 1 detik berlalu.Apa yang Anda cari disebut Filter Kalman . Ini sering digunakan untuk memuluskan data navigasi . Ini tidak selalu sepele, dan ada banyak penyetelan yang dapat Anda lakukan, tetapi ini adalah pendekatan yang sangat standar dan berfungsi dengan baik. Ada perpustakaan KFilter yang tersedia yang merupakan implementasi C ++.
Fallback saya berikutnya akan menjadi kotak paling cocok . Filter Kalman akan memuluskan data dengan mempertimbangkan kecepatan, sedangkan pendekatan kuadrat terkecil hanya akan menggunakan informasi posisi. Namun, jelas lebih mudah untuk diimplementasikan dan dipahami. Sepertinya Perpustakaan Ilmiah GNU mungkin memiliki implementasi ini.
sumber
Ini mungkin datang agak terlambat ...
Saya menulis KalmanLocationManager untuk Android ini, yang membungkus dua penyedia lokasi paling umum, Jaringan dan GPS, kalman-filter data, dan memberikan pembaruan ke
LocationListener
(seperti dua penyedia 'nyata').Saya menggunakannya sebagian besar untuk "interpolasi" antara pembacaan - untuk menerima pembaruan (prediksi posisi) setiap 100 milis misalnya (bukannya laju gps maksimum satu detik), yang memberi saya frame rate yang lebih baik ketika menjiwai posisi saya.
Sebenarnya, ia menggunakan tiga filter kalman, aktif untuk setiap dimensi: lintang, bujur dan ketinggian. Lagipula mereka mandiri.
Ini membuat matematika matriks jauh lebih mudah: daripada menggunakan satu matriks transisi keadaan 6x6, saya menggunakan 3 matriks 2x2 berbeda. Sebenarnya dalam kode, saya tidak menggunakan matriks sama sekali. Memecahkan semua persamaan dan semua nilai adalah primitif (ganda).
Kode sumber berfungsi, dan ada aktivitas demo. Maaf karena kurangnya javadoc di beberapa tempat, saya akan menyusul.
sumber
Anda tidak harus menghitung kecepatan dari perubahan posisi per waktu. GPS mungkin memiliki posisi yang tidak akurat, tetapi memiliki kecepatan yang akurat (di atas 5km / jam). Jadi gunakan kecepatan dari cap lokasi GPS. Dan lebih jauh Anda tidak harus melakukannya dengan tentu saja, meskipun itu berfungsi sebagian besar waktu.
Posisi GPS, seperti yang disampaikan, sudah difilter Kalman, Anda mungkin tidak dapat meningkatkan, dalam postprocessing biasanya Anda tidak memiliki informasi yang sama seperti chip GPS.
Anda dapat memuluskannya, tetapi ini juga menimbulkan kesalahan.
Pastikan bahwa Anda menghapus posisi ketika perangkat diam, ini menghapus posisi melompat, bahwa beberapa perangkat / Konfigurasi tidak menghapus.
sumber
Saya biasanya menggunakan accelerometer. Perubahan posisi yang tiba-tiba dalam waktu singkat menyiratkan akselerasi tinggi. Jika ini tidak tercermin dalam telemetri accelerometer, hampir pasti karena perubahan pada satelit "tiga terbaik" yang digunakan untuk menghitung posisi (yang saya sebut sebagai teleportasi GPS).
Ketika sebuah aset dalam keadaan diam dan melompat-lompat karena GPS teleporting, jika Anda secara progresif menghitung centroid Anda secara efektif memotong set kerang yang lebih besar dan lebih besar, meningkatkan presisi.
Untuk melakukan ini ketika aset tidak diam, Anda harus memperkirakan kemungkinan posisi dan orientasi berikutnya berdasarkan kecepatan, heading, linier, dan data percepatan rotasi (jika Anda memiliki gyro). Ini kurang lebih apa yang dilakukan oleh filter K yang terkenal. Anda bisa mendapatkan semuanya dalam perangkat keras untuk sekitar $ 150 pada AHRS yang mengandung segalanya kecuali modul GPS, dan dengan jack untuk menghubungkan satu. Ini memiliki CPU dan Kalman filtering on board; hasilnya stabil dan cukup baik. Bimbingan inersia sangat tahan terhadap jitter tetapi hanyut dengan waktu. GPS rentan terhadap jitter tetapi tidak melayang dengan waktu, mereka praktis dibuat untuk saling mengimbangi.
sumber
Salah satu metode yang menggunakan lebih sedikit matematika / teori adalah untuk sampel 2, 5, 7, atau 10 titik data sekaligus dan menentukan yang outlier. Ukuran outlier yang kurang akurat dibandingkan dengan Kalman Filter adalah menggunakan algoritma berikut untuk mengambil semua jarak pasangan yang bijaksana antara titik dan membuang yang paling jauh dari yang lain. Biasanya nilai-nilai itu diganti dengan nilai yang paling dekat dengan nilai outlying yang Anda ganti
Sebagai contoh
Menghaluskan pada lima titik sampel A, B, C, D, E
ATOTAL = SUM jarak AB AC AD AE
BTOTAL = SUM jarak AB BC BD BE
CTOTAL = SUM jarak AC BC CD CE
DTOTAL = SUM jarak DA DB DC DE
ETOTAL = SUM jarak EA EB EC DE
Jika BTOTAL adalah terbesar, Anda akan mengganti titik B dengan D jika BD = min {AB, BC, BD, BE}
Smoothing ini menentukan outlier dan dapat ditambah dengan menggunakan titik tengah BD bukan titik D untuk menghaluskan garis posisi. Jarak tempuh Anda dapat bervariasi dan ada lebih banyak solusi yang ketat secara matematis.
sumber
Untuk kotak yang paling pas, berikut adalah beberapa hal lain yang dapat Anda coba:
Hanya karena kuadratnya paling sesuai tidak berarti bahwa itu harus linier. Anda paling tidak bisa-kuadrat-cocok kurva kuadrat ke data, maka ini akan cocok dengan skenario di mana pengguna mempercepat. (Perhatikan bahwa dengan kuadrat terkecil yang saya maksud menggunakan koordinat sebagai variabel dependen dan waktu sebagai variabel independen.)
Anda juga dapat mencoba menimbang titik data berdasarkan akurasi yang dilaporkan. Ketika akurasinya rendah, titik-titik data tersebut lebih rendah.
Hal lain yang mungkin ingin Anda coba daripada menampilkan satu titik, jika akurasinya rendah, tampilkan lingkaran atau sesuatu yang menunjukkan kisaran di mana pengguna dapat didasarkan pada akurasi yang dilaporkan. (Inilah yang dilakukan aplikasi Google Maps bawaan iPhone.)
sumber
Anda juga dapat menggunakan spline. Masukkan nilai-nilai yang Anda miliki dan sisipkan poin di antara poin yang diketahui. Menghubungkan ini dengan fit-kuadrat, rata-rata bergerak atau filter kalman (seperti yang disebutkan dalam jawaban lain) memberi Anda kemampuan untuk menghitung poin di antara poin "diketahui" Anda.
Mampu menginterpolasi nilai-nilai antara yang diketahui memberi Anda transisi yang bagus dan / masuk akal / perkiraan data apa yang akan hadir jika Anda memiliki kesetiaan yang lebih tinggi. http://en.wikipedia.org/wiki/Spline_interpolation
Splines yang berbeda memiliki karakteristik yang berbeda. Yang saya lihat paling umum digunakan adalah Akima dan Cubic splines.
Algoritme lain yang perlu dipertimbangkan adalah algoritma penyederhanaan garis Ramer-Douglas-Peucker, cukup umum digunakan dalam penyederhanaan data GPS. ( http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm )
sumber
Kembali ke Filter Kalman ... Saya menemukan implementasi C untuk filter Kalman untuk data GPS di sini: http://github.com/lacker/ikalman Saya belum mencobanya, tetapi tampaknya menjanjikan.
sumber
Dipetakan ke CoffeeScript jika ada yang tertarik. ** sunting -> maaf menggunakan backbone juga, tetapi Anda mendapatkan idenya.
Dimodifikasi sedikit untuk menerima suar dengan attrib
sumber
@lat
dan@lng
ditetapkan. Seharusnya+=
lebih daripada=
Saya telah mengubah kode Java dari @Stochastically ke Kotlin
sumber
Berikut ini adalah implementasi Javascript dari implementasi Java @ Stochastically untuk siapa pun yang membutuhkannya:
Contoh penggunaan:
sumber