Integrate asynchronous GPS IMU fusion
This commit is contained in:
+135
-13
@@ -12,6 +12,55 @@ Bu bölüm yeni bir geliştirme oturumunun nereden devam edeceğini tek yerde
|
||||
özetler. Aşağıdaki Python model ve bare-metal C uygulaması aynı problemi çözer,
|
||||
fakat aynı program değildir:
|
||||
|
||||
### Asenkron IMU/GPS düzeltmesi ve sentetik oran matrisi
|
||||
|
||||
Önceki prototipte 52 Hz ST akışından yalnız yaklaşık 250 ms'de bir ham örnek
|
||||
seçiliyordu. Bu inertial downsampling değildir: kısa gyro hareketi iki seçilen
|
||||
örneğin arasında kalınca değişen gravity vektörü görülüyor, dönüş görülmüyor ve
|
||||
yanlış yatay ivme entegre ediliyordu. Linux C hızlı-eğim testinde bu yol 8.169 m
|
||||
tepe yatay hata ve 1.554 m/s kalıcı hız üretti.
|
||||
|
||||
Bu seçim katmanı kaldırıldı. Artık her raw sample kendi timestamp'iyle işlenir;
|
||||
ardışık accel/gyro örnekleri midpoint mechanization ile entegre edilir. GPS,
|
||||
IMU'dan bağımsız bir position observation'dır. WLS yalnız geçerli olduğunda
|
||||
ölçüm epoch'unda uygulanır; epoch iki IMU sample'ı arasındaysa input lineer
|
||||
interpolate edilir, update sonrası kalan IMU geçmişi current-time horizon'a
|
||||
replay edilir. Ana döngü IMU kuyruğunu WLS'den önce ve sonra tamamen boşaltır.
|
||||
|
||||
`async_rate_matrix_test.c` aynı üretim C kaynaklarına 52 Hz timestamp'li IMU,
|
||||
100/200/1000 ms GPS, 73/310 ms delivery delay, farklı eksenlerde ivmelenme ve
|
||||
fren, yaw dönüşü ve 10--18 s GPS outage verir. Sonuçlar sırasıyla 0.172/0.180/
|
||||
0.389 m yatay RMSE ve outage sırasında 0.634/0.671/0.822 m tepe hatadır; üçünde
|
||||
de GPS recovery kabul edilmiş, false ZUPT ve NIS reject sıfırdır. Tam GPS'siz
|
||||
koşu da kendine konum feed etmeden yerel dead-reckoning yapar: global origin
|
||||
false kalır, kovaryans büyür ve 25 s sonunda 3.674 m drift oluşur. Bu drift
|
||||
gizlenmez; mutlak konumun IMU-only durumda gözlenememesinin beklenen sonucudur.
|
||||
|
||||
`gps_reacquisition_test.c`, canlı UART'ta görülen kötü ilk GPS fix'i senaryosunu
|
||||
ENU'da 80/40/-170 m başlangıç ofsetiyle tekrarlar. Hard NIS kapısı tek başına
|
||||
sonraki doğru fix'leri sürekli reddettiği için fusion engine zaman tabanlı bir
|
||||
position reacquisition uygular: son başarılı position fusion üzerinden yedi
|
||||
saniye timeout geçtikten ve en az üç rejected fix kendi içinde devamlı olduktan
|
||||
sonra yalnız position state resetlenir. Hız, attitude ve IMU bias'ları korunur.
|
||||
Test 100/200/1000 ms GPS periyotlarında sıfır son hata üretir; ayrı
|
||||
150/-120/+80 m tek-fix testi aykırı ölçümün reddedildiğini ve state reset
|
||||
oluşturmadığını doğrular.
|
||||
|
||||
Testin `--trace` seçeneği UART'a benzer `IMU ts=...`, `GPS ts=... arrival=...`
|
||||
satırları üretir. Standart regression komutu:
|
||||
|
||||
```sh
|
||||
make -C soc/software/fusion/tests test
|
||||
```
|
||||
|
||||
`platform_scenario_matrix_test.c` ayrıca stationary/tilt/vibration, yaya,
|
||||
trafik ışığında duran otomobil ve ani dönüşlü/yüksek ivmeli uçak profillerini;
|
||||
200/500/1000 ms GNSS ile 19/20/200/300 ms IMU'nun 48 kombinasyonunda çalıştırır.
|
||||
GNSS dört uydu kullanır, ilk bölümde 5--10 m, sonra 3--5 m sınıfı yatay gürültü,
|
||||
3 saniye outage ve 2 saniye tutarlı büyük hata içerir. Kısa hata yedi saniyelik
|
||||
recovery timeout'unu açamaz. 200/300 ms IMU yüksek dinamikteki doğruluk kaybıyla
|
||||
birlikte açıkça raporlanır; test bunu daha sık IMU varmış gibi gizlemez.
|
||||
|
||||
```text
|
||||
Offline model:
|
||||
UART GPS + IMU logları -> Python parser -> fixed/adaptive ESKF -> CSV/grafik/harita
|
||||
@@ -213,16 +262,16 @@ yoktur.
|
||||
|
||||
Temel parçalar:
|
||||
|
||||
- `gps_system/src/eskf.c`: ENU konum/hız, body-to-ENU quaternion, accel bias,
|
||||
- `gps_system/src/fusion/eskf.c`: ENU konum/hız, body-to-ENU quaternion, accel bias,
|
||||
gyro bias ve 15x15 covariance içeren 15-hata-durumlu ESKF;
|
||||
- `gps_system/src/fusion_motion.c`: bootstrap/stationary/moving/candidate
|
||||
- `gps_system/src/fusion/fusion_motion.c`: bootstrap/stationary/moving/candidate
|
||||
durum makinesi, filtrelenmiş jerk ve ZUPT izni;
|
||||
- `gps_system/src/fusion_engine.c`: başlangıç kalibrasyonu, asenkron IMU/GPS,
|
||||
- `gps_system/src/fusion/fusion_engine.c`: başlangıç kalibrasyonu, asenkron IMU/GPS,
|
||||
NIS kapısı ve gecikmiş GPS için fixed-lag IMU replay;
|
||||
- `gps_system/src/fusion_gps_adapter.c`: WGS-84 LLH/ECEF/ENU dönüşümü ve
|
||||
- `gps_system/src/fusion/fusion_gps_adapter.c`: WGS-84 LLH/ECEF/ENU dönüşümü ve
|
||||
covariance tabanı;
|
||||
- `gps_system/src/tdk_icm42688.c`: ICM-42688-P SPI/INT1 sürücüsü;
|
||||
- `gps_system/src/navigation_fusion.c`: GPS ve IMU kuyruklarını algoritmaya
|
||||
- `gps_system/src/drivers/imu/tdk_icm42688.c`: ICM-42688-P SPI/INT1 sürücüsü;
|
||||
- `gps_system/src/fusion/navigation_fusion.c`: GPS ve IMU kuyruklarını algoritmaya
|
||||
bağlayan üst koordinatör.
|
||||
|
||||
### ESKF state ve matematik sınırı
|
||||
@@ -270,6 +319,64 @@ Default ESKF process/başlangıç değerleri:
|
||||
| Maksimum propagation alt adımı | 20 ms |
|
||||
| Konum NIS kapısı | 16.266236, 3 DOF %99.9 |
|
||||
|
||||
### Innovation rejection, recovery ve katman siniri (2026-07-16)
|
||||
|
||||
Standart ESKF position update'i tek basina buyuk ve kalici bir baslangic
|
||||
ofsetini duzeltemez. GPS--INS residual'i NIS kapisini astiginda olcum state'e
|
||||
hic uygulanmaz; state GPS'e yaklasmadigi icin sonraki dogru GPS fix'leri de
|
||||
ayni nedenle sonsuza kadar reddedilebilir. NIS yalniz iki bilgi kaynaginin
|
||||
tutarsiz oldugunu soyler. GPS'in mi hatali, yoksa ataletsel cozumun mu yanlis
|
||||
ankrajlandigini matematiksel update tek basina belirleyemez.
|
||||
|
||||
Bu nedenle sorumluluk iki katmana ayrilir:
|
||||
|
||||
- `eskf.c` innovation, innovation covariance, NIS gate, kabul edilmis Kalman
|
||||
correction ve covariance bakimindan dogru position-reset primitive'ini
|
||||
icerir. Rejected olcumu gizlice correction'a sokmaz ve NIS'i bypass etmez.
|
||||
- `fusion_engine.c` sensor gecmisi ve zaman bilgisine sahip supervisor'dur.
|
||||
Ardisik rejected GNSS fix'lerinin kendi aralarinda zamansal olarak tutarli
|
||||
olup olmadigini izler ve gerekli recovery/reset kararini burada verir.
|
||||
|
||||
Mevcut yalın recovery, son başarılı position fusion'dan sonra yedi saniyelik
|
||||
timeout dolmuşsa ve en az üç rejected position fix'i kendi arasında zamansal
|
||||
tutarlıysa yalnız position state ve position covariance'ini GNSS'e yeniden
|
||||
ankrajlar. Position cross-covariance'lari gecersiz korelasyon tasimamasi icin
|
||||
sifirlanir; velocity, attitude ve IMU bias state'leri korunur. Hard NIS gate
|
||||
aktif kalir ve tek aykiri olcum reset uretemez. Bu bir innovation-bypass
|
||||
workaround'u degil, kontrollu state recovery mekanizmasidir.
|
||||
|
||||
PX4 EKF2 de ayni temel ayrimi yapar. Generic `fuseHorizontalPosition()` yalniz
|
||||
innovation testinden gecen olcumu fuse eder. GNSS'e baslama, quality check,
|
||||
`time_last_fuse` timeout'u, state reset, fusion stop ve sensor-fault kararlari
|
||||
ayri GNSS control akisindadir. Otomatik modda baska yatay konum kaynagi yoksa
|
||||
uzun fusion timeout'undan sonra GNSS'e reset yapilabilir; alternatif aiding
|
||||
varsa veya dead-reckoning politikasinda GNSS durdurulabilir/fault kabul
|
||||
edilebilir. Kaynaklar:
|
||||
|
||||
- <https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/ekf2/EKF/aid_sources/gnss/gps_control.cpp>
|
||||
- <https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/ekf2/EKF/position_fusion.cpp>
|
||||
- <https://docs.px4.io/main/en/advanced_config/tuning_the_ecl_ekf>
|
||||
|
||||
Mevcut recovery PX4'teki aiding yoneticisinin sade bare-metal karsiligidir;
|
||||
nihai mimari hedefi asagidaki acik GNSS aiding durum makinesidir:
|
||||
|
||||
```text
|
||||
DISABLED -> STARTING -> FUSING -> FAULTED/RECOVERING
|
||||
```
|
||||
|
||||
Karar yalniz rejected-candidate suresine degil son basarili position fusion
|
||||
zamanina baglanmalidir. Uydu sayisi, finite covariance, DOP, WLS integrity ve
|
||||
alternatif aiding kaynaklari birlikte degerlendirilmelidir. Tam dort uyduda
|
||||
WLS residual redundancy/chi-square DOF bulunmadigi icin temporal consistency
|
||||
daha onemlidir. Ileride Doppler velocity ayri innovation, fusion timeout ve
|
||||
velocity-reset politikasi ile fuse edilmelidir. Yatay position ve height da
|
||||
barometre gibi ek kaynaklar geldiginde birbirinden bagimsiz yonetilmelidir.
|
||||
|
||||
Baslangic GNSS'i icin mutlak bir dogruluk referansi yoksa tutarli fakat yanlis
|
||||
bir GNSS kumesini otomatik olarak gercek konumdan ayirmak temel olarak mumkun
|
||||
degildir. Kisa bir stable-fix/startup-quality penceresi riski azaltir, fakat
|
||||
spoofing veya tutarli multipath'e karsi tek basina kanit degildir.
|
||||
|
||||
### Asenkron veri akışı ve timestamp
|
||||
|
||||
IMU ve GPS aynı local monotonic CPU/CLINT tick alanında timestamp edilir.
|
||||
@@ -313,6 +420,13 @@ verir. Yaw gravity ile gözlenemediği için başlangıçta sıfır referanslı
|
||||
Benzer şekilde stationary IMU ile yatay accel bias ve küçük tilt tamamen
|
||||
ayrılamaz; sonraki GPS/kinematik update'ler bu error-state'leri düzeltir.
|
||||
|
||||
IMU motion-state eşikleri tanılama için tutulur, fakat ZUPT yetkisini tek başına
|
||||
vermez. PX4 ayrımına uygun olarak `fusion_rest_detector` titreşim metriklerini
|
||||
izler ve dışarıdan gelen `platform_landed` kapısıyla birleşir. Prototipin unarmed
|
||||
bench modu landed=true başlar; gerçek araç kontrolü bu değeri kendi state'inden
|
||||
güncellemelidir. Sessiz IMU, landed=false iken sabit hızlı hareketi stationary
|
||||
ilan edemez.
|
||||
|
||||
Motion-state default eşikleri:
|
||||
|
||||
| Karar parametresi | Değer |
|
||||
@@ -328,12 +442,20 @@ Motion-state default eşikleri:
|
||||
| Stationary'e dönüş quiet dwell | 1.0 s |
|
||||
| Zayıf hareket doğrulaması | 3 ardışık IMU örneği |
|
||||
|
||||
Güçlü accel/gyro/jerk veya yüksek ESKF hızı stationary state'ten tek örnekte
|
||||
çıkabilir. Geri dönüş daha konservatiftir: quiet IMU, düşük ESKF hızı, aktif
|
||||
GNSS-moving veto olmaması ve 1 s dwell birlikte gerekir. ZUPT ile zero-gyro
|
||||
update yalnız gerçek `STATIONARY` state'inde, her IMU örneğinde değil 20 Hz'de
|
||||
uygulanır. ZUPT velocity sigma 0.03 m/s, zero-gyro sigma eksen başına
|
||||
0.01 deg/s'dir.
|
||||
Güçlü accel/gyro/jerk veya yüksek ESKF hızı motion tanılamasını tek örnekte
|
||||
moving'e çıkarabilir. ZUPT ve zero-gyro ise yalnız ardışık iki timestamp'li
|
||||
örnekte dış supervisor `vehicle_at_rest=true` verdiğinde 200 ms periyotla
|
||||
uygulanır. ZUPT velocity sigma 0.20 m/s'dir. Zero-gyro aynı 200 ms penceredeki
|
||||
delta-angle toplamından ortalama açısal hız üretir; tek bir örneği bias diye
|
||||
kabul etmez. Bu politika PX4 EKF2 `ZeroVelocityUpdate`/`ZeroGyroUpdate` ve land
|
||||
detector katman ayrımının bare-metal karşılığıdır.
|
||||
|
||||
Kaynaklar:
|
||||
|
||||
- <https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/ekf2/EKF/aid_sources/ZeroVelocityUpdate.cpp>
|
||||
- <https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/ekf2/EKF/aid_sources/ZeroGyroUpdate.cpp>
|
||||
- <https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/land_detector/LandDetector.cpp>
|
||||
- <https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/sensors/vehicle_imu/VehicleIMU.cpp>
|
||||
|
||||
GPS motion evidence, ardışık kabul edilmiş ENU konumları arasındaki yatay
|
||||
displacement için 2 DOF `9.21034` (%99) NIS ve en az 0.50 m/s hız ister. Moving
|
||||
@@ -836,7 +958,7 @@ azınlık TOW'unu çoğunluğa kopyalayan geçici recovery yolu da kaldırıldı
|
||||
veya problemli kanal reject edilir. TOW değeri sessizce başka kanalın
|
||||
değeriyle değiştirilmez.
|
||||
|
||||
Üretim kodu `header/gps_time_anchor.h` ve `src/gps_time_anchor.c` içindedir.
|
||||
Üretim kodu `header/gps/gps_time_anchor.h` ve `src/gps/gps_time_anchor.c` içindedir.
|
||||
`parse_subframe()` artık TOW state'ini değiştirmez; yalnız HOW TOW değerini
|
||||
dışarı verir. `gps_time_from_sample_anchor()` her nav-solve için GPS zamanını
|
||||
son HOW ve iki receiver-sample latch'i arasındaki farktan baştan üretir.
|
||||
|
||||
Reference in New Issue
Block a user